This commit is contained in:
mohuanzui
2026-06-02 12:55:53 +08:00
commit 9fd2426ac5
5188 changed files with 215542 additions and 0 deletions

View File

@@ -0,0 +1 @@
isolated

0
install/COLCON_IGNORE Normal file
View File

View File

@@ -0,0 +1,407 @@
# Copyright 2016-2019 Dirk Thomas
# Licensed under the Apache License, Version 2.0
import argparse
from collections import OrderedDict
import os
from pathlib import Path
import sys
FORMAT_STR_COMMENT_LINE = '# {comment}'
FORMAT_STR_SET_ENV_VAR = 'Set-Item -Path "Env:{name}" -Value "{value}"'
FORMAT_STR_USE_ENV_VAR = '$env:{name}'
FORMAT_STR_INVOKE_SCRIPT = '_colcon_prefix_powershell_source_script "{script_path}"' # noqa: E501
FORMAT_STR_REMOVE_LEADING_SEPARATOR = '' # noqa: E501
FORMAT_STR_REMOVE_TRAILING_SEPARATOR = '' # noqa: E501
DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate'
DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate'
DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists'
DSV_TYPE_SET = 'set'
DSV_TYPE_SET_IF_UNSET = 'set-if-unset'
DSV_TYPE_SOURCE = 'source'
def main(argv=sys.argv[1:]): # noqa: D103
parser = argparse.ArgumentParser(
description='Output shell commands for the packages in topological '
'order')
parser.add_argument(
'primary_extension',
help='The file extension of the primary shell')
parser.add_argument(
'additional_extension', nargs='?',
help='The additional file extension to be considered')
parser.add_argument(
'--merged-install', action='store_true',
help='All install prefixes are merged into a single location')
args = parser.parse_args(argv)
packages = get_packages(Path(__file__).parent, args.merged_install)
ordered_packages = order_packages(packages)
for pkg_name in ordered_packages:
if _include_comments():
print(
FORMAT_STR_COMMENT_LINE.format_map(
{'comment': 'Package: ' + pkg_name}))
prefix = os.path.abspath(os.path.dirname(__file__))
if not args.merged_install:
prefix = os.path.join(prefix, pkg_name)
for line in get_commands(
pkg_name, prefix, args.primary_extension,
args.additional_extension
):
print(line)
for line in _remove_ending_separators():
print(line)
def get_packages(prefix_path, merged_install):
"""
Find packages based on colcon-specific files created during installation.
:param Path prefix_path: The install prefix path of all packages
:param bool merged_install: The flag if the packages are all installed
directly in the prefix or if each package is installed in a subdirectory
named after the package
:returns: A mapping from the package name to the set of runtime
dependencies
:rtype: dict
"""
packages = {}
# since importing colcon_core isn't feasible here the following constant
# must match colcon_core.location.get_relative_package_index_path()
subdirectory = 'share/colcon-core/packages'
if merged_install:
# return if workspace is empty
if not (prefix_path / subdirectory).is_dir():
return packages
# find all files in the subdirectory
for p in (prefix_path / subdirectory).iterdir():
if not p.is_file():
continue
if p.name.startswith('.'):
continue
add_package_runtime_dependencies(p, packages)
else:
# for each subdirectory look for the package specific file
for p in prefix_path.iterdir():
if not p.is_dir():
continue
if p.name.startswith('.'):
continue
p = p / subdirectory / p.name
if p.is_file():
add_package_runtime_dependencies(p, packages)
# remove unknown dependencies
pkg_names = set(packages.keys())
for k in packages.keys():
packages[k] = {d for d in packages[k] if d in pkg_names}
return packages
def add_package_runtime_dependencies(path, packages):
"""
Check the path and if it exists extract the packages runtime dependencies.
:param Path path: The resource file containing the runtime dependencies
:param dict packages: A mapping from package names to the sets of runtime
dependencies to add to
"""
content = path.read_text()
dependencies = set(content.split(os.pathsep) if content else [])
packages[path.name] = dependencies
def order_packages(packages):
"""
Order packages topologically.
:param dict packages: A mapping from package name to the set of runtime
dependencies
:returns: The package names
:rtype: list
"""
# select packages with no dependencies in alphabetical order
to_be_ordered = list(packages.keys())
ordered = []
while to_be_ordered:
pkg_names_without_deps = [
name for name in to_be_ordered if not packages[name]]
if not pkg_names_without_deps:
reduce_cycle_set(packages)
raise RuntimeError(
'Circular dependency between: ' + ', '.join(sorted(packages)))
pkg_names_without_deps.sort()
pkg_name = pkg_names_without_deps[0]
to_be_ordered.remove(pkg_name)
ordered.append(pkg_name)
# remove item from dependency lists
for k in list(packages.keys()):
if pkg_name in packages[k]:
packages[k].remove(pkg_name)
return ordered
def reduce_cycle_set(packages):
"""
Reduce the set of packages to the ones part of the circular dependency.
:param dict packages: A mapping from package name to the set of runtime
dependencies which is modified in place
"""
last_depended = None
while len(packages) > 0:
# get all remaining dependencies
depended = set()
for pkg_name, dependencies in packages.items():
depended = depended.union(dependencies)
# remove all packages which are not dependent on
for name in list(packages.keys()):
if name not in depended:
del packages[name]
if last_depended:
# if remaining packages haven't changed return them
if last_depended == depended:
return packages.keys()
# otherwise reduce again
last_depended = depended
def _include_comments():
# skipping comment lines when COLCON_TRACE is not set speeds up the
# processing especially on Windows
return bool(os.environ.get('COLCON_TRACE'))
def get_commands(pkg_name, prefix, primary_extension, additional_extension):
commands = []
package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv')
if os.path.exists(package_dsv_path):
commands += process_dsv_file(
package_dsv_path, prefix, primary_extension, additional_extension)
return commands
def process_dsv_file(
dsv_path, prefix, primary_extension=None, additional_extension=None
):
commands = []
if _include_comments():
commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path}))
with open(dsv_path, 'r') as h:
content = h.read()
lines = content.splitlines()
basenames = OrderedDict()
for i, line in enumerate(lines):
# skip over empty or whitespace-only lines
if not line.strip():
continue
# skip over comments
if line.startswith('#'):
continue
try:
type_, remainder = line.split(';', 1)
except ValueError:
raise RuntimeError(
"Line %d in '%s' doesn't contain a semicolon separating the "
'type from the arguments' % (i + 1, dsv_path))
if type_ != DSV_TYPE_SOURCE:
# handle non-source lines
try:
commands += handle_dsv_types_except_source(
type_, remainder, prefix)
except RuntimeError as e:
raise RuntimeError(
"Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e
else:
# group remaining source lines by basename
path_without_ext, ext = os.path.splitext(remainder)
if path_without_ext not in basenames:
basenames[path_without_ext] = set()
assert ext.startswith('.')
ext = ext[1:]
if ext in (primary_extension, additional_extension):
basenames[path_without_ext].add(ext)
# add the dsv extension to each basename if the file exists
for basename, extensions in basenames.items():
if not os.path.isabs(basename):
basename = os.path.join(prefix, basename)
if os.path.exists(basename + '.dsv'):
extensions.add('dsv')
for basename, extensions in basenames.items():
if not os.path.isabs(basename):
basename = os.path.join(prefix, basename)
if 'dsv' in extensions:
# process dsv files recursively
commands += process_dsv_file(
basename + '.dsv', prefix, primary_extension=primary_extension,
additional_extension=additional_extension)
elif primary_extension in extensions and len(extensions) == 1:
# source primary-only files
commands += [
FORMAT_STR_INVOKE_SCRIPT.format_map({
'prefix': prefix,
'script_path': basename + '.' + primary_extension})]
elif additional_extension in extensions:
# source non-primary files
commands += [
FORMAT_STR_INVOKE_SCRIPT.format_map({
'prefix': prefix,
'script_path': basename + '.' + additional_extension})]
return commands
def handle_dsv_types_except_source(type_, remainder, prefix):
commands = []
if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET):
try:
env_name, value = remainder.split(';', 1)
except ValueError:
raise RuntimeError(
"doesn't contain a semicolon separating the environment name "
'from the value')
try_prefixed_value = os.path.join(prefix, value) if value else prefix
if os.path.exists(try_prefixed_value):
value = try_prefixed_value
if type_ == DSV_TYPE_SET:
commands += _set(env_name, value)
elif type_ == DSV_TYPE_SET_IF_UNSET:
commands += _set_if_unset(env_name, value)
else:
assert False
elif type_ in (
DSV_TYPE_APPEND_NON_DUPLICATE,
DSV_TYPE_PREPEND_NON_DUPLICATE,
DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS
):
try:
env_name_and_values = remainder.split(';')
except ValueError:
raise RuntimeError(
"doesn't contain a semicolon separating the environment name "
'from the values')
env_name = env_name_and_values[0]
values = env_name_and_values[1:]
for value in values:
if not value:
value = prefix
elif not os.path.isabs(value):
value = os.path.join(prefix, value)
if (
type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and
not os.path.exists(value)
):
comment = f'skip extending {env_name} with not existing ' \
f'path: {value}'
if _include_comments():
commands.append(
FORMAT_STR_COMMENT_LINE.format_map({'comment': comment}))
elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE:
commands += _append_unique_value(env_name, value)
else:
commands += _prepend_unique_value(env_name, value)
else:
raise RuntimeError(
'contains an unknown environment hook type: ' + type_)
return commands
env_state = {}
def _append_unique_value(name, value):
global env_state
if name not in env_state:
if os.environ.get(name):
env_state[name] = set(os.environ[name].split(os.pathsep))
else:
env_state[name] = set()
# append even if the variable has not been set yet, in case a shell script sets the
# same variable without the knowledge of this Python script.
# later _remove_ending_separators() will cleanup any unintentional leading separator
extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': extend + value})
if value not in env_state[name]:
env_state[name].add(value)
else:
if not _include_comments():
return []
line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
return [line]
def _prepend_unique_value(name, value):
global env_state
if name not in env_state:
if os.environ.get(name):
env_state[name] = set(os.environ[name].split(os.pathsep))
else:
env_state[name] = set()
# prepend even if the variable has not been set yet, in case a shell script sets the
# same variable without the knowledge of this Python script.
# later _remove_ending_separators() will cleanup any unintentional trailing separator
extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name})
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': value + extend})
if value not in env_state[name]:
env_state[name].add(value)
else:
if not _include_comments():
return []
line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
return [line]
# generate commands for removing prepended underscores
def _remove_ending_separators():
# do nothing if the shell extension does not implement the logic
if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None:
return []
global env_state
commands = []
for name in env_state:
# skip variables that already had values before this script started prepending
if name in os.environ:
continue
commands += [
FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}),
FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})]
return commands
def _set(name, value):
global env_state
env_state[name] = value
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': value})
return [line]
def _set_if_unset(name, value):
global env_state
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': value})
if env_state.get(name, os.environ.get(name)):
line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
return [line]
if __name__ == '__main__': # pragma: no cover
try:
rc = main()
except RuntimeError as e:
print(str(e), file=sys.stderr)
rc = 1
sys.exit(rc)

View File

@@ -0,0 +1,407 @@
# Copyright 2016-2019 Dirk Thomas
# Licensed under the Apache License, Version 2.0
import argparse
from collections import OrderedDict
import os
from pathlib import Path
import sys
FORMAT_STR_COMMENT_LINE = '# {comment}'
FORMAT_STR_SET_ENV_VAR = 'export {name}="{value}"'
FORMAT_STR_USE_ENV_VAR = '${name}'
FORMAT_STR_INVOKE_SCRIPT = 'COLCON_CURRENT_PREFIX="{prefix}" _colcon_prefix_sh_source_script "{script_path}"' # noqa: E501
FORMAT_STR_REMOVE_LEADING_SEPARATOR = 'if [ "$(echo -n ${name} | head -c 1)" = ":" ]; then export {name}=${{{name}#?}} ; fi' # noqa: E501
FORMAT_STR_REMOVE_TRAILING_SEPARATOR = 'if [ "$(echo -n ${name} | tail -c 1)" = ":" ]; then export {name}=${{{name}%?}} ; fi' # noqa: E501
DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate'
DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate'
DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists'
DSV_TYPE_SET = 'set'
DSV_TYPE_SET_IF_UNSET = 'set-if-unset'
DSV_TYPE_SOURCE = 'source'
def main(argv=sys.argv[1:]): # noqa: D103
parser = argparse.ArgumentParser(
description='Output shell commands for the packages in topological '
'order')
parser.add_argument(
'primary_extension',
help='The file extension of the primary shell')
parser.add_argument(
'additional_extension', nargs='?',
help='The additional file extension to be considered')
parser.add_argument(
'--merged-install', action='store_true',
help='All install prefixes are merged into a single location')
args = parser.parse_args(argv)
packages = get_packages(Path(__file__).parent, args.merged_install)
ordered_packages = order_packages(packages)
for pkg_name in ordered_packages:
if _include_comments():
print(
FORMAT_STR_COMMENT_LINE.format_map(
{'comment': 'Package: ' + pkg_name}))
prefix = os.path.abspath(os.path.dirname(__file__))
if not args.merged_install:
prefix = os.path.join(prefix, pkg_name)
for line in get_commands(
pkg_name, prefix, args.primary_extension,
args.additional_extension
):
print(line)
for line in _remove_ending_separators():
print(line)
def get_packages(prefix_path, merged_install):
"""
Find packages based on colcon-specific files created during installation.
:param Path prefix_path: The install prefix path of all packages
:param bool merged_install: The flag if the packages are all installed
directly in the prefix or if each package is installed in a subdirectory
named after the package
:returns: A mapping from the package name to the set of runtime
dependencies
:rtype: dict
"""
packages = {}
# since importing colcon_core isn't feasible here the following constant
# must match colcon_core.location.get_relative_package_index_path()
subdirectory = 'share/colcon-core/packages'
if merged_install:
# return if workspace is empty
if not (prefix_path / subdirectory).is_dir():
return packages
# find all files in the subdirectory
for p in (prefix_path / subdirectory).iterdir():
if not p.is_file():
continue
if p.name.startswith('.'):
continue
add_package_runtime_dependencies(p, packages)
else:
# for each subdirectory look for the package specific file
for p in prefix_path.iterdir():
if not p.is_dir():
continue
if p.name.startswith('.'):
continue
p = p / subdirectory / p.name
if p.is_file():
add_package_runtime_dependencies(p, packages)
# remove unknown dependencies
pkg_names = set(packages.keys())
for k in packages.keys():
packages[k] = {d for d in packages[k] if d in pkg_names}
return packages
def add_package_runtime_dependencies(path, packages):
"""
Check the path and if it exists extract the packages runtime dependencies.
:param Path path: The resource file containing the runtime dependencies
:param dict packages: A mapping from package names to the sets of runtime
dependencies to add to
"""
content = path.read_text()
dependencies = set(content.split(os.pathsep) if content else [])
packages[path.name] = dependencies
def order_packages(packages):
"""
Order packages topologically.
:param dict packages: A mapping from package name to the set of runtime
dependencies
:returns: The package names
:rtype: list
"""
# select packages with no dependencies in alphabetical order
to_be_ordered = list(packages.keys())
ordered = []
while to_be_ordered:
pkg_names_without_deps = [
name for name in to_be_ordered if not packages[name]]
if not pkg_names_without_deps:
reduce_cycle_set(packages)
raise RuntimeError(
'Circular dependency between: ' + ', '.join(sorted(packages)))
pkg_names_without_deps.sort()
pkg_name = pkg_names_without_deps[0]
to_be_ordered.remove(pkg_name)
ordered.append(pkg_name)
# remove item from dependency lists
for k in list(packages.keys()):
if pkg_name in packages[k]:
packages[k].remove(pkg_name)
return ordered
def reduce_cycle_set(packages):
"""
Reduce the set of packages to the ones part of the circular dependency.
:param dict packages: A mapping from package name to the set of runtime
dependencies which is modified in place
"""
last_depended = None
while len(packages) > 0:
# get all remaining dependencies
depended = set()
for pkg_name, dependencies in packages.items():
depended = depended.union(dependencies)
# remove all packages which are not dependent on
for name in list(packages.keys()):
if name not in depended:
del packages[name]
if last_depended:
# if remaining packages haven't changed return them
if last_depended == depended:
return packages.keys()
# otherwise reduce again
last_depended = depended
def _include_comments():
# skipping comment lines when COLCON_TRACE is not set speeds up the
# processing especially on Windows
return bool(os.environ.get('COLCON_TRACE'))
def get_commands(pkg_name, prefix, primary_extension, additional_extension):
commands = []
package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv')
if os.path.exists(package_dsv_path):
commands += process_dsv_file(
package_dsv_path, prefix, primary_extension, additional_extension)
return commands
def process_dsv_file(
dsv_path, prefix, primary_extension=None, additional_extension=None
):
commands = []
if _include_comments():
commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path}))
with open(dsv_path, 'r') as h:
content = h.read()
lines = content.splitlines()
basenames = OrderedDict()
for i, line in enumerate(lines):
# skip over empty or whitespace-only lines
if not line.strip():
continue
# skip over comments
if line.startswith('#'):
continue
try:
type_, remainder = line.split(';', 1)
except ValueError:
raise RuntimeError(
"Line %d in '%s' doesn't contain a semicolon separating the "
'type from the arguments' % (i + 1, dsv_path))
if type_ != DSV_TYPE_SOURCE:
# handle non-source lines
try:
commands += handle_dsv_types_except_source(
type_, remainder, prefix)
except RuntimeError as e:
raise RuntimeError(
"Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e
else:
# group remaining source lines by basename
path_without_ext, ext = os.path.splitext(remainder)
if path_without_ext not in basenames:
basenames[path_without_ext] = set()
assert ext.startswith('.')
ext = ext[1:]
if ext in (primary_extension, additional_extension):
basenames[path_without_ext].add(ext)
# add the dsv extension to each basename if the file exists
for basename, extensions in basenames.items():
if not os.path.isabs(basename):
basename = os.path.join(prefix, basename)
if os.path.exists(basename + '.dsv'):
extensions.add('dsv')
for basename, extensions in basenames.items():
if not os.path.isabs(basename):
basename = os.path.join(prefix, basename)
if 'dsv' in extensions:
# process dsv files recursively
commands += process_dsv_file(
basename + '.dsv', prefix, primary_extension=primary_extension,
additional_extension=additional_extension)
elif primary_extension in extensions and len(extensions) == 1:
# source primary-only files
commands += [
FORMAT_STR_INVOKE_SCRIPT.format_map({
'prefix': prefix,
'script_path': basename + '.' + primary_extension})]
elif additional_extension in extensions:
# source non-primary files
commands += [
FORMAT_STR_INVOKE_SCRIPT.format_map({
'prefix': prefix,
'script_path': basename + '.' + additional_extension})]
return commands
def handle_dsv_types_except_source(type_, remainder, prefix):
commands = []
if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET):
try:
env_name, value = remainder.split(';', 1)
except ValueError:
raise RuntimeError(
"doesn't contain a semicolon separating the environment name "
'from the value')
try_prefixed_value = os.path.join(prefix, value) if value else prefix
if os.path.exists(try_prefixed_value):
value = try_prefixed_value
if type_ == DSV_TYPE_SET:
commands += _set(env_name, value)
elif type_ == DSV_TYPE_SET_IF_UNSET:
commands += _set_if_unset(env_name, value)
else:
assert False
elif type_ in (
DSV_TYPE_APPEND_NON_DUPLICATE,
DSV_TYPE_PREPEND_NON_DUPLICATE,
DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS
):
try:
env_name_and_values = remainder.split(';')
except ValueError:
raise RuntimeError(
"doesn't contain a semicolon separating the environment name "
'from the values')
env_name = env_name_and_values[0]
values = env_name_and_values[1:]
for value in values:
if not value:
value = prefix
elif not os.path.isabs(value):
value = os.path.join(prefix, value)
if (
type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and
not os.path.exists(value)
):
comment = f'skip extending {env_name} with not existing ' \
f'path: {value}'
if _include_comments():
commands.append(
FORMAT_STR_COMMENT_LINE.format_map({'comment': comment}))
elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE:
commands += _append_unique_value(env_name, value)
else:
commands += _prepend_unique_value(env_name, value)
else:
raise RuntimeError(
'contains an unknown environment hook type: ' + type_)
return commands
env_state = {}
def _append_unique_value(name, value):
global env_state
if name not in env_state:
if os.environ.get(name):
env_state[name] = set(os.environ[name].split(os.pathsep))
else:
env_state[name] = set()
# append even if the variable has not been set yet, in case a shell script sets the
# same variable without the knowledge of this Python script.
# later _remove_ending_separators() will cleanup any unintentional leading separator
extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': extend + value})
if value not in env_state[name]:
env_state[name].add(value)
else:
if not _include_comments():
return []
line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
return [line]
def _prepend_unique_value(name, value):
global env_state
if name not in env_state:
if os.environ.get(name):
env_state[name] = set(os.environ[name].split(os.pathsep))
else:
env_state[name] = set()
# prepend even if the variable has not been set yet, in case a shell script sets the
# same variable without the knowledge of this Python script.
# later _remove_ending_separators() will cleanup any unintentional trailing separator
extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name})
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': value + extend})
if value not in env_state[name]:
env_state[name].add(value)
else:
if not _include_comments():
return []
line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
return [line]
# generate commands for removing prepended underscores
def _remove_ending_separators():
# do nothing if the shell extension does not implement the logic
if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None:
return []
global env_state
commands = []
for name in env_state:
# skip variables that already had values before this script started prepending
if name in os.environ:
continue
commands += [
FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}),
FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})]
return commands
def _set(name, value):
global env_state
env_state[name] = value
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': value})
return [line]
def _set_if_unset(name, value):
global env_state
line = FORMAT_STR_SET_ENV_VAR.format_map(
{'name': name, 'value': value})
if env_state.get(name, os.environ.get(name)):
line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
return [line]
if __name__ == '__main__': # pragma: no cover
try:
rc = main()
except RuntimeError as e:
print(str(e), file=sys.stderr)
rc = 1
sys.exit(rc)

View File

@@ -0,0 +1,58 @@
#!/usr/bin/env python3
"""
命令行发送导航目标点到 Nav2
用法:
ros2 run gc_bringup nav_goal 1.0 2.0 0.5 # 去 (1.0, 2.0), yaw=0.5
ros2 run gc_bringup nav_goal 1.0 2.0 # 去 (1.0, 2.0), yaw=0.0
ros2 run gc_bringup nav_goal -2.0 0.0 3.14 # 去 (-2.0, 0.0), 面朝后
# 或使用 topic pub
ros2 topic pub /goal_pose geometry_msgs/PoseStamped "{header: {frame_id: 'map'}, pose: {position: {x: 1.0, y: 0.0}, orientation: {z: 0.0, w: 1.0}}}"
"""
import sys
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import PoseStamped
import math
class GoalSender(Node):
def __init__(self):
super().__init__('goal_sender')
self.publisher = self.create_publisher(PoseStamped, '/goal_pose', 10)
def send_goal(self, x: float, y: float, yaw: float = 0.0):
msg = PoseStamped()
msg.header.frame_id = 'map'
msg.header.stamp = self.get_clock().now().to_msg()
msg.pose.position.x = x
msg.pose.position.y = y
msg.pose.position.z = 0.0
msg.pose.orientation.z = math.sin(yaw / 2.0)
msg.pose.orientation.w = math.cos(yaw / 2.0)
self.publisher.publish(msg)
self.get_logger().info(f'发送导航目标: x={x:.2f}, y={y:.2f}, yaw={yaw:.2f}')
def main():
rclpy.init()
sender = GoalSender()
args = sys.argv[1:]
if len(args) < 2:
print("用法: ros2 run gc_bringup nav_goal <x> <y> [yaw]")
print("示例: ros2 run gc_bringup nav_goal 1.0 2.0 0.5")
sys.exit(1)
x = float(args[0])
y = float(args[1])
yaw = float(args[2]) if len(args) > 2 else 0.0
sender.send_goal(x, y, yaw)
rclpy.shutdown()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1 @@
gazebo_ros;robot_state_publisher;joint_state_publisher;rviz2;nav2_bringup;slam_toolbox;origincar_description;xacro;teleop_twist_keyboard;ament_lint_auto;ament_lint_common

View File

@@ -0,0 +1 @@
/home/guoch/test_ws/install/gc_bringup:/home/guoch/test_ws/install/origincar_description:/home/guoch/test_ws/install/gc_slamtoolbox:/home/guoch/test_ws/install/gc_slam_toolbox_fish:/home/guoch/test_ws/install/gc_navigation_fish:/home/guoch/test_ws/install/gc_navigation2_slamtoolbox:/home/guoch/test_ws/install/gc_navigation:/opt/ros/humble

View File

@@ -0,0 +1 @@
gazebo_ros:joint_state_publisher:nav2_bringup:origincar_description:robot_state_publisher:rviz2:slam_toolbox:teleop_twist_keyboard:xacro

View File

@@ -0,0 +1,14 @@
# generated from ament/cmake/core/templates/nameConfig-version.cmake.in
set(PACKAGE_VERSION "1.0.0")
set(PACKAGE_VERSION_EXACT False)
set(PACKAGE_VERSION_COMPATIBLE False)
if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}")
set(PACKAGE_VERSION_EXACT True)
set(PACKAGE_VERSION_COMPATIBLE True)
endif()
if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE True)
endif()

View File

@@ -0,0 +1,42 @@
# generated from ament/cmake/core/templates/nameConfig.cmake.in
# prevent multiple inclusion
if(_gc_bringup_CONFIG_INCLUDED)
# ensure to keep the found flag the same
if(NOT DEFINED gc_bringup_FOUND)
# explicitly set it to FALSE, otherwise CMake will set it to TRUE
set(gc_bringup_FOUND FALSE)
elseif(NOT gc_bringup_FOUND)
# use separate condition to avoid uninitialized variable warning
set(gc_bringup_FOUND FALSE)
endif()
return()
endif()
set(_gc_bringup_CONFIG_INCLUDED TRUE)
# output package information
if(NOT gc_bringup_FIND_QUIETLY)
message(STATUS "Found gc_bringup: 1.0.0 (${gc_bringup_DIR})")
endif()
# warn when using a deprecated package
if(NOT "" STREQUAL "")
set(_msg "Package 'gc_bringup' is deprecated")
# append custom deprecation text if available
if(NOT "" STREQUAL "TRUE")
set(_msg "${_msg} ()")
endif()
# optionally quiet the deprecation message
if(NOT ${gc_bringup_DEPRECATED_QUIET})
message(DEPRECATION "${_msg}")
endif()
endif()
# flag package as ament-based to distinguish it after being find_package()-ed
set(gc_bringup_FOUND_AMENT_PACKAGE TRUE)
# include all config extra files
set(_extras "")
foreach(_extra ${_extras})
include("${gc_bringup_DIR}/${_extra}")
endforeach()

View File

@@ -0,0 +1,60 @@
# =============================================================================
# slam_toolbox 定位模式参数
# 用于在已有地图上进行定位(替代 AMCL
# =============================================================================
slam_toolbox:
ros__parameters:
# 基本设置
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 参数
odom_frame: odom
map_frame: map
base_frame: base_footprint
scan_topic: /scan
use_sim_time: True
mode: localization
# 调试
debug_logging: false
throttle_scans: 1
transform_publish_period: 0.02
map_update_interval: 10.0
resolution: 0.05
max_laser_range: 3.5
minimum_time_interval: 0.5
transform_timeout: 0.2
tf_buffer_duration: 30.0
stack_size_to_use: 40000000
# 定位模式不需要回环检测
loop_search_maximum_distance: 3.0
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_search_space_dimension: 0.5
correlation_search_space_resolution: 0.01
correlation_search_space_smear_deviation: 0.1
# 回环闭合
loop_search_space_dimension: 8.0
loop_search_space_resolution: 0.05
loop_search_space_smear_deviation: 0.03
# 扫描匹配器
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

View File

@@ -0,0 +1,61 @@
# =============================================================================
# slam_toolbox 在线异步建图参数
# 用于实时 SLAM 建图
# =============================================================================
slam_toolbox:
ros__parameters:
# 基本设置
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 参数
odom_frame: odom
map_frame: map
base_frame: base_footprint
scan_topic: /scan
use_sim_time: True
mode: mapping
# 调试
debug_logging: false
throttle_scans: 1
transform_publish_period: 0.02
map_update_interval: 5.0
resolution: 0.05
max_laser_range: 3.5
minimum_time_interval: 0.5
transform_timeout: 0.2
tf_buffer_duration: 30.0
stack_size_to_use: 40000000
enable_interactive_mode: true
# 回环检测
loop_search_maximum_distance: 3.0
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_search_space_dimension: 0.5
correlation_search_space_resolution: 0.01
correlation_search_space_smear_deviation: 0.1
# 回环闭合
loop_search_space_dimension: 8.0
loop_search_space_resolution: 0.05
loop_search_space_smear_deviation: 0.03
# 扫描匹配器
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

View File

@@ -0,0 +1,411 @@
# =============================================================================
# Nav2 参数 — 阿克曼底盘 + AMCL + MPPI
# =============================================================================
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: 60
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
# ★ 自动设定初始位姿 — 不设置的话 map→odom 的 TF 不会发布
set_initial_pose: true
initial_pose:
x: 0.0
y: 0.0
z: 0.0
yaw: 0.0
robot_model_type: "nav2_amcl::DifferentialMotionModel"
save_pose_rate: 0.5
sigma_hit: 0.2
tf_broadcast: true
transform_tolerance: 10.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
amcl_map_client:
ros__parameters:
use_sim_time: True
amcl_rclcpp_node:
ros__parameters:
use_sim_time: True
bt_navigator:
ros__parameters:
use_sim_time: True
global_frame: map
robot_base_frame: base_footprint
odom_topic: /odom
bt_loop_duration: 10
default_server_timeout: 20
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_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_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_drive_on_heading_cancel_bt_node
bt_navigator_rclcpp_node:
ros__parameters:
use_sim_time: True
controller_server:
ros__parameters:
use_sim_time: True
controller_frequency: 30.0
controller_plugins: ["FollowPath"]
progress_checker:
plugin: "nav2_controller::SimpleProgressChecker"
required_movement_radius: 0.5
movement_time_allowance: 10.0
goal_checker:
plugin: "nav2_controller::SimpleGoalChecker"
xy_goal_tolerance: 0.25
yaw_goal_tolerance: 0.25
FollowPath:
plugin: "nav2_mppi_controller::MPPIController"
time_steps: 56
model_dt: 0.05
batch_size: 2000
vx_std: 0.2
vy_std: 0.0
wz_std: 0.4
vx_max: 0.5
vx_min: -0.35
vy_max: 0.0
wz_max: 1.9
iteration_count: 1
temperature: 0.3
gamma: 0.015
motion_model: "Ackermann"
visualize: false
TrajectoryVisualizer:
trajectory_step: 5
time_step: 3
AckermannConstraints:
min_turning_r: 0.4
critics:
- "ConstraintCritic"
- "CostCritic"
- "GoalCritic"
- "GoalAngleCritic"
- "PathAlignCritic"
- "PathFollowCritic"
- "PathAngleCritic"
- "PreferForwardCritic"
ConstraintCritic:
enabled: true
cost_power: 1
cost_weight: 4.0
GoalCritic:
enabled: true
cost_power: 1
cost_weight: 5.0
threshold_to_consider: 1.4
GoalAngleCritic:
enabled: true
cost_power: 1
cost_weight: 3.0
threshold_to_consider: 0.5
PreferForwardCritic:
enabled: true
cost_power: 1
cost_weight: 5.0
threshold_to_consider: 0.5
CostCritic:
enabled: true
cost_power: 1
cost_weight: 3.81
critical_cost: 300.0
consider_footprint: true
collision_cost: 1000000.0
near_goal_distance: 1.0
trajectory_point_step: 2
PathAlignCritic:
enabled: true
cost_power: 1
cost_weight: 14.0
max_path_occupancy_ratio: 0.05
trajectory_point_step: 4
threshold_to_consider: 0.5
offset_from_furthest: 20
use_path_orientations: false
PathFollowCritic:
enabled: true
cost_power: 1
cost_weight: 5.0
offset_from_furthest: 5
threshold_to_consider: 1.4
PathAngleCritic:
enabled: true
cost_power: 1
cost_weight: 2.0
offset_from_furthest: 4
threshold_to_consider: 0.5
max_angle_to_furthest: 1.0
forward_preference: true
controller_server_rclcpp_node:
ros__parameters:
use_sim_time: True
planner_server:
ros__parameters:
planner_plugins: ["GridBased"]
use_sim_time: True
GridBased:
plugin: "nav2_smac_planner/SmacPlannerHybrid"
downsample_costmap: false
downsampling_factor: 1
tolerance: 0.25
allow_unknown: true
max_iterations: 1000000
max_on_approach_iterations: 1000
max_planning_time: 5.0
motion_model_for_search: "REEDS_SHEPP"
angle_quantization_bins: 72
analytic_expansion_ratio: 3.5
analytic_expansion_max_length: 3.0
minimum_turning_radius: 0.40
reverse_penalty: 2.0
change_penalty: 0.0
non_straight_penalty: 1.2
cost_penalty: 2.0
retrospective_penalty: 0.015
lookup_table_size: 20.0
cache_obstacle_heuristic: false
viz_expansions: false
smooth_path: True
smoother:
max_iterations: 1000
w_smooth: 0.3
w_data: 0.2
tolerance: 1.0e-10
do_refinement: true
refinement_num: 2
planner_server_rclcpp_node:
ros__parameters:
use_sim_time: 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", "wait"]
spin:
plugin: "nav2_behaviors/Spin"
backup:
plugin: "nav2_behaviors/BackUp"
wait:
plugin: "nav2_behaviors/Wait"
global_frame: odom
robot_base_frame: base_footprint
transform_tolerance: 0.5
use_sim_time: True
simulate_ahead_time: 2.0
max_rotational_vel: 1.0
min_rotational_vel: 0.4
rotational_acc_lim: 3.2
behavior_server_rclcpp_node:
ros__parameters:
use_sim_time: True
local_costmap:
local_costmap:
ros__parameters:
update_frequency: 5.0
publish_frequency: 2.0
transform_tolerance: 0.5
global_frame: odom
robot_base_frame: base_footprint
use_sim_time: True
rolling_window: true
width: 3
height: 3
resolution: 0.05
footprint: "[[0.14, 0.085], [0.14, -0.085], [-0.14, -0.085], [-0.14, 0.085]]"
footprint_padding: 0.02
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:
map_subscribe_transient_local: True
always_send_full_costmap: True
local_costmap_client:
ros__parameters:
use_sim_time: True
local_costmap_rclcpp_node:
ros__parameters:
use_sim_time: True
global_costmap:
global_costmap:
ros__parameters:
use_sim_time: True
transform_tolerance: 0.5
update_frequency: 1.0
publish_frequency: 1.0
global_frame: map
robot_base_frame: base_footprint
footprint: "[[0.14, 0.085], [0.14, -0.085], [-0.14, -0.085], [-0.14, 0.085]]"
footprint_padding: 0.02
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
global_costmap_client:
ros__parameters:
use_sim_time: True
global_costmap_rclcpp_node:
ros__parameters:
use_sim_time: True
map_server:
ros__parameters:
use_sim_time: True
yaml_filename: ""
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
robot_state_publisher:
ros__parameters:
use_sim_time: True
waypoint_follower:
ros__parameters:
loop_rate: 20
use_sim_time: True
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

View File

@@ -0,0 +1 @@
prepend-non-duplicate;AMENT_PREFIX_PATH;

View File

@@ -0,0 +1,4 @@
# copied from
# ament_cmake_core/cmake/environment_hooks/environment/ament_prefix_path.sh
ament_prepend_unique_value AMENT_PREFIX_PATH "$AMENT_CURRENT_PREFIX"

View File

@@ -0,0 +1 @@
prepend-non-duplicate-if-exists;PATH;bin

View File

@@ -0,0 +1,5 @@
# copied from ament_cmake_core/cmake/environment_hooks/environment/path.sh
if [ -d "$AMENT_CURRENT_PREFIX/bin" ]; then
ament_prepend_unique_value PATH "$AMENT_CURRENT_PREFIX/bin"
fi

View File

@@ -0,0 +1 @@
prepend-non-duplicate;CMAKE_PREFIX_PATH;

View File

@@ -0,0 +1,3 @@
# generated from colcon_powershell/shell/template/hook_prepend_value.ps1.em
colcon_prepend_unique_value CMAKE_PREFIX_PATH "$env:COLCON_CURRENT_PREFIX"

View File

@@ -0,0 +1,3 @@
# generated from colcon_core/shell/template/hook_prepend_value.sh.em
_colcon_prepend_unique_value CMAKE_PREFIX_PATH "$COLCON_CURRENT_PREFIX"

View File

@@ -0,0 +1,207 @@
#!/usr/bin/env python3
# =============================================================================
# gc_bringup — AMCL 导航模式 (直接启动 Nav2 节点)
# 启动 Gazebo + 机器人 + Nav2 (AMCL 定位)
# =============================================================================
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import (DeclareLaunchArgument, ExecuteProcess,
TimerAction)
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, Command
from launch_ros.actions import Node
from launch_ros.parameter_descriptions import ParameterValue
def generate_launch_description():
bringup_dir = get_package_share_directory('gc_bringup')
origincar_dir = get_package_share_directory('origincar_description')
# ==================== 参数 ====================
use_sim_time = LaunchConfiguration('use_sim_time', default='true')
use_gazebo = LaunchConfiguration('use_gazebo', default='true')
use_rviz = LaunchConfiguration('use_rviz', default='false')
world = LaunchConfiguration('world', default=os.path.join(
origincar_dir, 'world', 'gc_world.world'))
map_yaml = LaunchConfiguration('map', default=os.path.join(
bringup_dir, 'maps', 'my_map.yaml'))
declare_use_sim_time = DeclareLaunchArgument('use_sim_time', default_value='true')
declare_use_gazebo = DeclareLaunchArgument('use_gazebo', default_value='true')
declare_use_rviz = DeclareLaunchArgument('use_rviz', default_value='false')
declare_world = DeclareLaunchArgument(
'world', default_value=os.path.join(origincar_dir, 'world', 'gc_world.world'))
declare_map = DeclareLaunchArgument(
'map', default_value=os.path.join(bringup_dir, 'maps', 'my_map.yaml'))
# ==================== 机器人模型 ====================
default_model_path = os.path.join(origincar_dir, 'urdf', 'origincar.urdf')
robot_description = ParameterValue(
Command(['xacro ', default_model_path]), value_type=str)
# ==================== Gazebo ====================
start_gazebo = ExecuteProcess(
condition=IfCondition(use_gazebo),
cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_init.so',
'-s', 'libgazebo_ros_factory.so', world],
output='screen')
spawn_robot = Node(
condition=IfCondition(use_gazebo),
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-entity', 'mycar', '-file', default_model_path,
'-x', '0.0', '-y', '0.0', '-z', '0.1'],
output='screen')
# ==================== TF & 机器人状态 ====================
robot_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher',
parameters=[{'robot_description': robot_description,
'use_sim_time': True, 'publish_frequency': 30.0}],
output='screen')
joint_state_publisher = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher',
parameters=[{'use_sim_time': True}], output='screen')
# ==================== Nav2 参数文件路径 ====================
nav2_params = os.path.join(bringup_dir, 'config', 'nav2_params.yaml')
# ==================== Map Server ====================
map_server = Node(
package='nav2_map_server',
executable='map_server',
name='map_server',
output='screen',
parameters=[nav2_params,
{'use_sim_time': True, 'yaml_filename': map_yaml}],
arguments=['--ros-args', '-p', 'use_sim_time:=True'],
)
# ==================== AMCL ====================
amcl = Node(
package='nav2_amcl',
executable='amcl',
name='amcl',
output='screen',
parameters=[nav2_params, {'use_sim_time': True}],
remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')],
arguments=['--ros-args', '-p', 'use_sim_time:=True'],
)
# ==================== Planner Server ====================
planner_server = Node(
package='nav2_planner',
executable='planner_server',
name='planner_server',
output='screen',
parameters=[nav2_params, {'use_sim_time': True}],
remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')],
arguments=['--ros-args', '-p', 'use_sim_time:=True'],
)
# ==================== Controller Server ====================
controller_server = Node(
package='nav2_controller',
executable='controller_server',
name='controller_server',
output='screen',
parameters=[nav2_params, {'use_sim_time': True}],
remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')],
arguments=['--ros-args', '-p', 'use_sim_time:=True'],
)
# ==================== Behavior Server ====================
behavior_server = Node(
package='nav2_behaviors',
executable='behavior_server',
name='behavior_server',
output='screen',
parameters=[nav2_params, {'use_sim_time': True}],
remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')],
arguments=['--ros-args', '-p', 'use_sim_time:=True'],
)
# ==================== BT Navigator ====================
bt_navigator = Node(
package='nav2_bt_navigator',
executable='bt_navigator',
name='bt_navigator',
output='screen',
parameters=[nav2_params, {'use_sim_time': True}],
remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')],
arguments=['--ros-args', '-p', 'use_sim_time:=True'],
)
# ==================== Waypoint Follower ====================
waypoint_follower = Node(
package='nav2_waypoint_follower',
executable='waypoint_follower',
name='waypoint_follower',
output='screen',
parameters=[nav2_params, {'use_sim_time': True}],
remappings=[('/tf', 'tf'), ('/tf_static', 'tf_static')],
arguments=['--ros-args', '-p', 'use_sim_time:=True'],
)
# ==================== Lifecycle Manager (map + amcl) ====================
lifecycle_localization = 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', 'amcl']}],
)
# ==================== Lifecycle Manager (nav nodes) ====================
lifecycle_navigation = Node(
package='nav2_lifecycle_manager',
executable='lifecycle_manager',
name='lifecycle_manager_navigation',
output='screen',
parameters=[{'use_sim_time': True, 'autostart': True,
'node_names': ['controller_server', 'planner_server',
'behavior_server', 'bt_navigator',
'waypoint_follower']}],
)
# ==================== RViz2 (可选) ====================
rviz_config = os.path.join(bringup_dir, 'rviz', 'navigation.rviz')
rviz_node = Node(
condition=IfCondition(use_rviz),
package='rviz2',
executable='rviz2',
name='rviz2',
arguments=['-d', rviz_config],
parameters=[{'use_sim_time': True}],
output='screen')
# ==================== 组装 ====================
ld = LaunchDescription()
ld.add_action(declare_use_sim_time)
ld.add_action(declare_use_gazebo)
ld.add_action(declare_use_rviz)
ld.add_action(declare_world)
ld.add_action(declare_map)
ld.add_action(start_gazebo)
ld.add_action(TimerAction(period=5.0, actions=[spawn_robot]))
ld.add_action(robot_state_publisher)
ld.add_action(joint_state_publisher)
ld.add_action(TimerAction(period=8.0, actions=[
map_server, amcl,
planner_server, controller_server, behavior_server, bt_navigator,
waypoint_follower,
lifecycle_localization, lifecycle_navigation,
rviz_node,
]))
return ld

View File

@@ -0,0 +1,150 @@
#!/usr/bin/env python3
# =============================================================================
# gc_bringup — slam_toolbox 定位 + 导航模式
# 使用 slam_toolbox 定位模式替代 AMCL适用于有 posegraph 的场景
# =============================================================================
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import (DeclareLaunchArgument, ExecuteProcess,
IncludeLaunchDescription, TimerAction)
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration, Command
from launch_ros.actions import Node
from launch_ros.parameter_descriptions import ParameterValue
def generate_launch_description():
# ============================ 包路径 ============================
bringup_dir = get_package_share_directory('gc_bringup')
origincar_dir = get_package_share_directory('origincar_description')
nav2_bringup_dir = get_package_share_directory('nav2_bringup')
# ============================ 启动参数 ============================
use_sim_time = LaunchConfiguration('use_sim_time', default='true')
use_gazebo = LaunchConfiguration('use_gazebo', default='true')
use_rviz = LaunchConfiguration('use_rviz', default='true')
world = LaunchConfiguration('world', default=os.path.join(
origincar_dir, 'world', 'gc_world.world'))
map_yaml = LaunchConfiguration('map', default=os.path.join(
bringup_dir, 'maps', 'my_map.yaml'))
declare_use_sim_time = DeclareLaunchArgument('use_sim_time', default_value='true')
declare_use_gazebo = DeclareLaunchArgument('use_gazebo', default_value='true')
declare_use_rviz = DeclareLaunchArgument('use_rviz', default_value='true')
declare_world = DeclareLaunchArgument(
'world', default_value=os.path.join(origincar_dir, 'world', 'gc_world.world'))
declare_map = DeclareLaunchArgument(
'map', default_value=os.path.join(bringup_dir, 'maps', 'my_map.yaml'))
# ============================ 机器人模型 ============================
default_model_path = os.path.join(origincar_dir, 'urdf', 'origincar.urdf')
robot_description = ParameterValue(
Command(['xacro ', default_model_path]), value_type=str)
# ============================ Gazebo ============================
start_gazebo = ExecuteProcess(
condition=IfCondition(use_gazebo),
cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_init.so',
'-s', 'libgazebo_ros_factory.so', world],
output='screen'
)
spawn_robot = Node(
condition=IfCondition(use_gazebo),
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-entity', 'mycar',
'-file', default_model_path,
'-x', '0.0', '-y', '0.0', '-z', '0.1'],
output='screen'
)
# ============================ TF & 机器人状态 ============================
robot_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher',
parameters=[{
'robot_description': robot_description,
'use_sim_time': True,
'publish_frequency': 30.0
}],
output='screen'
)
joint_state_publisher = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher',
parameters=[{'use_sim_time': True}],
output='screen'
)
# ============================ slam_toolbox 定位模式 ============================
map_base_path = os.path.join(bringup_dir, 'maps', 'my_map')
slam_localization_params = os.path.join(
bringup_dir, 'config', 'mapper_params_localization.yaml')
slam_toolbox_node = Node(
package='slam_toolbox',
executable='localization_slam_toolbox_node',
name='slam_toolbox',
output='screen',
parameters=[
slam_localization_params,
{
'map_file_name': map_base_path,
'use_sim_time': True
}
]
)
# ============================ Nav2 Bringup (关闭内部定位,用 slam_toolbox) ============================
nav2_params = os.path.join(bringup_dir, 'config', 'nav2_params.yaml')
nav2_launch_path = os.path.join(nav2_bringup_dir, 'launch', 'bringup_launch.py')
nav2_bringup = IncludeLaunchDescription(
PythonLaunchDescriptionSource(nav2_launch_path),
launch_arguments={
'map': map_yaml,
'use_sim_time': use_sim_time,
'params_file': nav2_params,
'slam': 'False',
'autostart': 'True',
'use_composition': 'False',
}.items(),
)
# ============================ RViz2 ============================
rviz_config = os.path.join(bringup_dir, 'rviz', 'navigation.rviz')
rviz_node = Node(
condition=IfCondition(use_rviz),
package='rviz2',
executable='rviz2',
name='rviz2',
arguments=['-d', rviz_config],
parameters=[{'use_sim_time': True}],
output='screen'
)
# ============================ 组装 ============================
ld = LaunchDescription()
ld.add_action(declare_use_sim_time)
ld.add_action(declare_use_gazebo)
ld.add_action(declare_use_rviz)
ld.add_action(declare_world)
ld.add_action(declare_map)
ld.add_action(start_gazebo)
ld.add_action(TimerAction(period=5.0, actions=[spawn_robot]))
ld.add_action(robot_state_publisher)
ld.add_action(joint_state_publisher)
ld.add_action(TimerAction(
period=8.0,
actions=[slam_toolbox_node, nav2_bringup, rviz_node]
))
return ld

View File

@@ -0,0 +1,153 @@
#!/usr/bin/env python3
# =============================================================================
# gc_bringup — SLAM 建图模式
# 启动 Gazebo + 机器人 + slam_toolbox 在线异步建图 + RViz
# =============================================================================
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess, TimerAction
from launch.conditions import IfCondition, UnlessCondition
from launch.substitutions import LaunchConfiguration, Command
from launch_ros.actions import Node
from launch_ros.parameter_descriptions import ParameterValue
def generate_launch_description():
# ============================ 包路径 ============================
bringup_dir = get_package_share_directory('gc_bringup')
origincar_dir = get_package_share_directory('origincar_description')
# ============================ 启动参数 ============================
use_sim_time = LaunchConfiguration('use_sim_time', default='true')
use_gazebo = LaunchConfiguration('use_gazebo', default='true')
use_rviz = LaunchConfiguration('use_rviz', default='false')
world = LaunchConfiguration('world', default=os.path.join(
origincar_dir, 'world', 'gc_world.world'))
declare_use_sim_time = DeclareLaunchArgument(
'use_sim_time', default_value='true',
description='Use simulation (Gazebo) clock if true')
declare_use_gazebo = DeclareLaunchArgument(
'use_gazebo', default_value='true',
description='Start Gazebo simulation')
declare_use_rviz = DeclareLaunchArgument(
'use_rviz', default_value='false',
description='Start RViz2 (set true if you need local visualization)')
declare_world = DeclareLaunchArgument(
'world', default_value=os.path.join(origincar_dir, 'world', 'gc_world.world'),
description='Full path to Gazebo world file')
# ============================ 机器人模型 ============================
default_model_path = os.path.join(origincar_dir, 'urdf', 'origincar.urdf')
robot_description = ParameterValue(
Command(['xacro ', default_model_path]), value_type=str)
# ============================ Gazebo ============================
start_gazebo = ExecuteProcess(
condition=IfCondition(use_gazebo),
cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_init.so',
'-s', 'libgazebo_ros_factory.so', world],
output='screen'
)
spawn_robot = Node(
condition=IfCondition(use_gazebo),
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-entity', 'mycar',
'-file', default_model_path,
'-x', '0.0', '-y', '0.0', '-z', '0.1'],
output='screen'
)
# ============================ TF & 机器人状态 ============================
robot_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher',
parameters=[{
'robot_description': robot_description,
'use_sim_time': True,
'publish_frequency': 30.0
}],
output='screen'
)
joint_state_publisher = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher',
parameters=[{'use_sim_time': True}],
output='screen'
)
# ============================ SLAM Toolbox (在线异步建图) ============================
slam_params_file = os.path.join(
bringup_dir, 'config', 'mapper_params_online_async.yaml')
slam_toolbox_node = Node(
package='slam_toolbox',
executable='async_slam_toolbox_node',
name='slam_toolbox',
output='screen',
parameters=[slam_params_file, {'use_sim_time': True}],
remappings=[('/scan', '/scan')]
)
# ============================ RViz2 ============================
rviz_config = os.path.join(bringup_dir, 'rviz', 'slam_mapping.rviz')
rviz_node = Node(
condition=IfCondition(use_rviz),
package='rviz2',
executable='rviz2',
name='rviz2',
arguments=['-d', rviz_config],
parameters=[{'use_sim_time': True}],
output='screen'
)
# ============================ 键盘遥控 (用于驱动机器人建图) ============================
use_teleop = LaunchConfiguration('use_teleop', default='true')
declare_use_teleop = DeclareLaunchArgument(
'use_teleop', default_value='true',
description='Start keyboard teleop for driving')
teleop_node = Node(
condition=IfCondition(use_teleop),
package='teleop_twist_keyboard',
executable='teleop_twist_keyboard',
name='teleop_twist_keyboard',
prefix='xterm -e',
output='screen',
remappings=[('/cmd_vel', '/cmd_vel')],
parameters=[{'use_sim_time': True}]
)
# ============================ 组装启动描述 ============================
ld = LaunchDescription()
ld.add_action(declare_use_sim_time)
ld.add_action(declare_use_gazebo)
ld.add_action(declare_use_rviz)
ld.add_action(declare_world)
ld.add_action(declare_use_teleop)
ld.add_action(start_gazebo)
# 等 Gazebo 启动后再生成机器人 (延迟 5 秒)
ld.add_action(TimerAction(
period=5.0,
actions=[spawn_robot]
))
ld.add_action(robot_state_publisher)
ld.add_action(joint_state_publisher)
# 等机器人生成后再启动 SLAM (延迟 3 秒)
ld.add_action(TimerAction(
period=8.0,
actions=[slam_toolbox_node, teleop_node, rviz_node]
))
return ld

View File

@@ -0,0 +1,46 @@
# generated from ament_package/template/package_level/local_setup.bash.in
# source local_setup.sh from same directory as this file
_this_path=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" && pwd)
# provide AMENT_CURRENT_PREFIX to shell script
AMENT_CURRENT_PREFIX=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`/../.." && pwd)
# store AMENT_CURRENT_PREFIX to restore it before each environment hook
_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX
# trace output
if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
echo "# . \"$_this_path/local_setup.sh\""
fi
. "$_this_path/local_setup.sh"
unset _this_path
# unset AMENT_ENVIRONMENT_HOOKS
# if not appending to them for return
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
unset AMENT_ENVIRONMENT_HOOKS
fi
# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# list all environment hooks of this package
# source all shell-specific environment hooks of this package
# if not returning them
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
_package_local_setup_IFS=$IFS
IFS=":"
for _hook in $AMENT_ENVIRONMENT_HOOKS; do
# restore AMENT_CURRENT_PREFIX for each environment hook
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# restore IFS before sourcing other files
IFS=$_package_local_setup_IFS
. "$_hook"
done
unset _hook
IFS=$_package_local_setup_IFS
unset _package_local_setup_IFS
unset AMENT_ENVIRONMENT_HOOKS
fi
unset _package_local_setup_AMENT_CURRENT_PREFIX
unset AMENT_CURRENT_PREFIX

View File

@@ -0,0 +1,2 @@
source;share/gc_bringup/environment/ament_prefix_path.sh
source;share/gc_bringup/environment/path.sh

View File

@@ -0,0 +1,184 @@
# generated from ament_package/template/package_level/local_setup.sh.in
# since this file is sourced use either the provided AMENT_CURRENT_PREFIX
# or fall back to the destination set at configure time
: ${AMENT_CURRENT_PREFIX:="/home/guoch/test_ws/install/gc_bringup"}
if [ ! -d "$AMENT_CURRENT_PREFIX" ]; then
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
echo "The compile time prefix path '$AMENT_CURRENT_PREFIX' doesn't " \
"exist. Consider sourcing a different extension than '.sh'." 1>&2
else
AMENT_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
fi
fi
# function to append values to environment variables
# using colons as separators and avoiding leading separators
ament_append_value() {
# arguments
_listname="$1"
_value="$2"
#echo "listname $_listname"
#eval echo "list value \$$_listname"
#echo "value $_value"
# avoid leading separator
eval _values=\"\$$_listname\"
if [ -z "$_values" ]; then
eval export $_listname=\"$_value\"
#eval echo "set list \$$_listname"
else
# field separator must not be a colon
_ament_append_value_IFS=$IFS
unset IFS
eval export $_listname=\"\$$_listname:$_value\"
#eval echo "append list \$$_listname"
IFS=$_ament_append_value_IFS
unset _ament_append_value_IFS
fi
unset _values
unset _value
unset _listname
}
# function to append non-duplicate values to environment variables
# using colons as separators and avoiding leading separators
ament_append_unique_value() {
# arguments
_listname=$1
_value=$2
#echo "listname $_listname"
#eval echo "list value \$$_listname"
#echo "value $_value"
# check if the list contains the value
eval _values=\$$_listname
_duplicate=
_ament_append_unique_value_IFS=$IFS
IFS=":"
if [ "$AMENT_SHELL" = "zsh" ]; then
ament_zsh_to_array _values
fi
for _item in $_values; do
# ignore empty strings
if [ -z "$_item" ]; then
continue
fi
if [ $_item = $_value ]; then
_duplicate=1
fi
done
unset _item
# append only non-duplicates
if [ -z "$_duplicate" ]; then
# avoid leading separator
if [ -z "$_values" ]; then
eval $_listname=\"$_value\"
#eval echo "set list \$$_listname"
else
# field separator must not be a colon
unset IFS
eval $_listname=\"\$$_listname:$_value\"
#eval echo "append list \$$_listname"
fi
fi
IFS=$_ament_append_unique_value_IFS
unset _ament_append_unique_value_IFS
unset _duplicate
unset _values
unset _value
unset _listname
}
# function to prepend non-duplicate values to environment variables
# using colons as separators and avoiding trailing separators
ament_prepend_unique_value() {
# arguments
_listname="$1"
_value="$2"
#echo "listname $_listname"
#eval echo "list value \$$_listname"
#echo "value $_value"
# check if the list contains the value
eval _values=\"\$$_listname\"
_duplicate=
_ament_prepend_unique_value_IFS=$IFS
IFS=":"
if [ "$AMENT_SHELL" = "zsh" ]; then
ament_zsh_to_array _values
fi
for _item in $_values; do
# ignore empty strings
if [ -z "$_item" ]; then
continue
fi
if [ "$_item" = "$_value" ]; then
_duplicate=1
fi
done
unset _item
# prepend only non-duplicates
if [ -z "$_duplicate" ]; then
# avoid trailing separator
if [ -z "$_values" ]; then
eval export $_listname=\"$_value\"
#eval echo "set list \$$_listname"
else
# field separator must not be a colon
unset IFS
eval export $_listname=\"$_value:\$$_listname\"
#eval echo "prepend list \$$_listname"
fi
fi
IFS=$_ament_prepend_unique_value_IFS
unset _ament_prepend_unique_value_IFS
unset _duplicate
unset _values
unset _value
unset _listname
}
# unset AMENT_ENVIRONMENT_HOOKS
# if not appending to them for return
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
unset AMENT_ENVIRONMENT_HOOKS
fi
# list all environment hooks of this package
ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/gc_bringup/environment/ament_prefix_path.sh"
ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/gc_bringup/environment/path.sh"
# source all shell-specific environment hooks of this package
# if not returning them
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
_package_local_setup_IFS=$IFS
IFS=":"
if [ "$AMENT_SHELL" = "zsh" ]; then
ament_zsh_to_array AMENT_ENVIRONMENT_HOOKS
fi
for _hook in $AMENT_ENVIRONMENT_HOOKS; do
if [ -f "$_hook" ]; then
# restore IFS before sourcing other files
IFS=$_package_local_setup_IFS
# trace output
if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
echo "# . \"$_hook\""
fi
. "$_hook"
fi
done
unset _hook
IFS=$_package_local_setup_IFS
unset _package_local_setup_IFS
unset AMENT_ENVIRONMENT_HOOKS
fi
# reset AMENT_CURRENT_PREFIX after each package
# allowing to source multiple package-level setup files
unset AMENT_CURRENT_PREFIX

View File

@@ -0,0 +1,59 @@
# generated from ament_package/template/package_level/local_setup.zsh.in
AMENT_SHELL=zsh
# source local_setup.sh from same directory as this file
_this_path=$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)
# provide AMENT_CURRENT_PREFIX to shell script
AMENT_CURRENT_PREFIX=$(builtin cd -q "`dirname "${(%):-%N}"`/../.." > /dev/null && pwd)
# store AMENT_CURRENT_PREFIX to restore it before each environment hook
_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX
# function to convert array-like strings into arrays
# to wordaround SH_WORD_SPLIT not being set
ament_zsh_to_array() {
local _listname=$1
local _dollar="$"
local _split="{="
local _to_array="(\"$_dollar$_split$_listname}\")"
eval $_listname=$_to_array
}
# trace output
if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
echo "# . \"$_this_path/local_setup.sh\""
fi
# the package-level local_setup file unsets AMENT_CURRENT_PREFIX
. "$_this_path/local_setup.sh"
unset _this_path
# unset AMENT_ENVIRONMENT_HOOKS
# if not appending to them for return
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
unset AMENT_ENVIRONMENT_HOOKS
fi
# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# list all environment hooks of this package
# source all shell-specific environment hooks of this package
# if not returning them
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
_package_local_setup_IFS=$IFS
IFS=":"
for _hook in $AMENT_ENVIRONMENT_HOOKS; do
# restore AMENT_CURRENT_PREFIX for each environment hook
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# restore IFS before sourcing other files
IFS=$_package_local_setup_IFS
. "$_hook"
done
unset _hook
IFS=$_package_local_setup_IFS
unset _package_local_setup_IFS
unset AMENT_ENVIRONMENT_HOOKS
fi
unset _package_local_setup_AMENT_CURRENT_PREFIX
unset AMENT_CURRENT_PREFIX

Binary file not shown.

View File

@@ -0,0 +1,7 @@
image: my_map.pgm
mode: trinary
resolution: 0.05
origin: [-9.95, -8.29, 0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.25

View File

@@ -0,0 +1,39 @@
# generated from colcon_bash/shell/template/package.bash.em
# This script extends the environment for this package.
# a bash script is able to determine its own path if necessary
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
# the prefix is two levels up from the package specific share directory
_colcon_package_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`/../.." > /dev/null && pwd)"
else
_colcon_package_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
fi
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
_colcon_package_bash_source_script() {
if [ -f "$1" ]; then
if [ -n "$COLCON_TRACE" ]; then
echo "# . \"$1\""
fi
. "$@"
else
echo "not found: \"$1\"" 1>&2
fi
}
# source sh script of this package
_colcon_package_bash_source_script "$_colcon_package_bash_COLCON_CURRENT_PREFIX/share/gc_bringup/package.sh"
# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced scripts
COLCON_CURRENT_PREFIX="$_colcon_package_bash_COLCON_CURRENT_PREFIX"
# source bash hooks
_colcon_package_bash_source_script "$COLCON_CURRENT_PREFIX/share/gc_bringup/local_setup.bash"
unset COLCON_CURRENT_PREFIX
unset _colcon_package_bash_source_script
unset _colcon_package_bash_COLCON_CURRENT_PREFIX

View File

@@ -0,0 +1,8 @@
source;share/gc_bringup/hook/cmake_prefix_path.ps1
source;share/gc_bringup/hook/cmake_prefix_path.dsv
source;share/gc_bringup/hook/cmake_prefix_path.sh
source;share/gc_bringup/local_setup.bash
source;share/gc_bringup/local_setup.dsv
source;share/gc_bringup/local_setup.ps1
source;share/gc_bringup/local_setup.sh
source;share/gc_bringup/local_setup.zsh

View File

@@ -0,0 +1,116 @@
# generated from colcon_powershell/shell/template/package.ps1.em
# function to append a value to a variable
# which uses colons as separators
# duplicates as well as leading separators are avoided
# first argument: the name of the result variable
# second argument: the value to be prepended
function colcon_append_unique_value {
param (
$_listname,
$_value
)
# get values from variable
if (Test-Path Env:$_listname) {
$_values=(Get-Item env:$_listname).Value
} else {
$_values=""
}
$_duplicate=""
# start with no values
$_all_values=""
# iterate over existing values in the variable
if ($_values) {
$_values.Split(";") | ForEach {
# not an empty string
if ($_) {
# not a duplicate of _value
if ($_ -eq $_value) {
$_duplicate="1"
}
if ($_all_values) {
$_all_values="${_all_values};$_"
} else {
$_all_values="$_"
}
}
}
}
# append only non-duplicates
if (!$_duplicate) {
# avoid leading separator
if ($_all_values) {
$_all_values="${_all_values};${_value}"
} else {
$_all_values="${_value}"
}
}
# export the updated variable
Set-Item env:\$_listname -Value "$_all_values"
}
# 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
function colcon_prepend_unique_value {
param (
$_listname,
$_value
)
# get values from variable
if (Test-Path Env:$_listname) {
$_values=(Get-Item env:$_listname).Value
} else {
$_values=""
}
# start with the new value
$_all_values="$_value"
# iterate over existing values in the variable
if ($_values) {
$_values.Split(";") | ForEach {
# not an empty string
if ($_) {
# not a duplicate of _value
if ($_ -ne $_value) {
# keep non-duplicate values
$_all_values="${_all_values};$_"
}
}
}
}
# export the updated variable
Set-Item env:\$_listname -Value "$_all_values"
}
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
function colcon_package_source_powershell_script {
param (
$_colcon_package_source_powershell_script
)
# source script with conditional trace output
if (Test-Path $_colcon_package_source_powershell_script) {
if ($env:COLCON_TRACE) {
echo ". '$_colcon_package_source_powershell_script'"
}
. "$_colcon_package_source_powershell_script"
} else {
Write-Error "not found: '$_colcon_package_source_powershell_script'"
}
}
# a powershell script is able to determine its own path
# the prefix is two levels up from the package specific share directory
$env:COLCON_CURRENT_PREFIX=(Get-Item $PSCommandPath).Directory.Parent.Parent.FullName
colcon_package_source_powershell_script "$env:COLCON_CURRENT_PREFIX\share/gc_bringup/hook/cmake_prefix_path.ps1"
colcon_package_source_powershell_script "$env:COLCON_CURRENT_PREFIX\share/gc_bringup/local_setup.ps1"
Remove-Item Env:\COLCON_CURRENT_PREFIX

View File

@@ -0,0 +1,87 @@
# generated from colcon_core/shell/template/package.sh.em
# This script extends the environment for this package.
# 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_prepend_unique_value() {
# arguments
_listname="$1"
_value="$2"
# get values from variable
eval _values=\"\$$_listname\"
# backup the field separator
_colcon_prepend_unique_value_IFS=$IFS
IFS=":"
# start with the new value
_all_values="$_value"
# workaround SH_WORD_SPLIT not being set in zsh
if [ "$(command -v colcon_zsh_convert_to_array)" ]; then
colcon_zsh_convert_to_array _values
fi
# 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
continue
fi
# keep non-duplicate values
_all_values="$_all_values:$_item"
done
unset _item
# restore the field separator
IFS=$_colcon_prepend_unique_value_IFS
unset _colcon_prepend_unique_value_IFS
# export the updated variable
eval export $_listname=\"$_all_values\"
unset _all_values
unset _values
unset _value
unset _listname
}
# 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_package_sh_COLCON_CURRENT_PREFIX="/home/guoch/test_ws/install/gc_bringup"
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
if [ ! -d "$_colcon_package_sh_COLCON_CURRENT_PREFIX" ]; then
echo "The build time path \"$_colcon_package_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_package_sh_COLCON_CURRENT_PREFIX
return 1
fi
COLCON_CURRENT_PREFIX="$_colcon_package_sh_COLCON_CURRENT_PREFIX"
fi
unset _colcon_package_sh_COLCON_CURRENT_PREFIX
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
_colcon_package_sh_source_script() {
if [ -f "$1" ]; then
if [ -n "$COLCON_TRACE" ]; then
echo "# . \"$1\""
fi
. "$@"
else
echo "not found: \"$1\"" 1>&2
fi
}
# source sh hooks
_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/gc_bringup/hook/cmake_prefix_path.sh"
_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/gc_bringup/local_setup.sh"
unset _colcon_package_sh_source_script
unset COLCON_CURRENT_PREFIX
# do not unset _colcon_prepend_unique_value since it might be used by non-primary shell hooks

View File

@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>gc_bringup</name>
<version>1.0.0</version>
<description>GC Robot Bringup: SLAM mapping and AMCL navigation for Ackermann robot with LiDAR</description>
<maintainer email="guoch@todo.todo">guoch</maintainer>
<license>Apache-2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<exec_depend>gazebo_ros</exec_depend>
<exec_depend>robot_state_publisher</exec_depend>
<exec_depend>joint_state_publisher</exec_depend>
<exec_depend>rviz2</exec_depend>
<exec_depend>nav2_bringup</exec_depend>
<exec_depend>slam_toolbox</exec_depend>
<exec_depend>origincar_description</exec_depend>
<exec_depend>xacro</exec_depend>
<exec_depend>teleop_twist_keyboard</exec_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>

View File

@@ -0,0 +1,50 @@
# generated from colcon_zsh/shell/template/package.zsh.em
# This script extends the environment for this package.
# a zsh script is able to determine its own path if necessary
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
# the prefix is two levels up from the package specific share directory
_colcon_package_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`/../.." > /dev/null && pwd)"
else
_colcon_package_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
fi
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
_colcon_package_zsh_source_script() {
if [ -f "$1" ]; then
if [ -n "$COLCON_TRACE" ]; then
echo "# . \"$1\""
fi
. "$@"
else
echo "not found: \"$1\"" 1>&2
fi
}
# function to convert array-like strings into arrays
# to workaround SH_WORD_SPLIT not being set
colcon_zsh_convert_to_array() {
local _listname=$1
local _dollar="$"
local _split="{="
local _to_array="(\"$_dollar$_split$_listname}\")"
eval $_listname=$_to_array
}
# source sh script of this package
_colcon_package_zsh_source_script "$_colcon_package_zsh_COLCON_CURRENT_PREFIX/share/gc_bringup/package.sh"
unset convert_zsh_to_array
# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced scripts
COLCON_CURRENT_PREFIX="$_colcon_package_zsh_COLCON_CURRENT_PREFIX"
# source zsh hooks
_colcon_package_zsh_source_script "$COLCON_CURRENT_PREFIX/share/gc_bringup/local_setup.zsh"
unset COLCON_CURRENT_PREFIX
unset _colcon_package_zsh_source_script
unset _colcon_package_zsh_COLCON_CURRENT_PREFIX

View File

@@ -0,0 +1,133 @@
Panels:
- Class: rviz_common/Displays
Name: Displays
- Class: rviz_common/Views
Name: Views
Visualization Manager:
Class: ""
Displays:
- Alpha: 0.8
Class: rviz_default_plugins/RobotModel
Enabled: true
Name: RobotModel
Robot Description: robot_description
Visual Enabled: true
- Class: rviz_default_plugins/TF
Enabled: true
Name: TF
Frame Timeout: 15
Marker Scale: 0.3
- Class: rviz_default_plugins/Map
Enabled: true
Name: Map
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /map
Update Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /map_updates
Color Scheme: map
Draw Behind: true
Use Timestamp: false
- Class: rviz_default_plugins/LaserScan
Enabled: true
Name: LaserScan
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Best Effort
Value: /scan
Size (m): 0.02
Style: Flat Squares
Decay Time: 0.3
Color Transformer: Intensity
- Class: rviz_default_plugins/Path
Enabled: true
Name: Global Plan
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /plan
Color: 25; 255; 0
Line Style: Dashed
- Class: rviz_default_plugins/Path
Enabled: true
Name: Local Plan
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /local_plan
Color: 255; 153; 0
- Class: rviz_default_plugins/Path
Enabled: true
Name: Smoothed Plan
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /smoothed_plan
Color: 255; 255; 0
- Class: rviz_default_plugins/Costmap
Enabled: true
Name: Local Costmap
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /local_costmap/costmap
Color Scheme: costmap
Draw Behind: false
- Class: rviz_default_plugins/Costmap
Enabled: false
Name: Global Costmap
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /global_costmap/costmap
Color Scheme: costmap
Draw Behind: false
- Alpha: 0.99
Class: rviz_default_plugins/ParticleCloud
Enabled: true
Name: AMCL Particle Swarm
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /particle_cloud
Color: 255; 0; 0
Style: Flat Squares
Enabled: true
Global Options:
Background Color: 48; 48; 48
Fixed Frame: map
Frame Rate: 30
Name: root
Tools:
- Class: rviz_default_plugins/Interact
- Class: rviz_default_plugins/MoveCamera
- Class: rviz_default_plugins/Select
- Class: rviz_default_plugins/SetInitialPose
Topic:
Value: /initialpose
- Class: rviz_default_plugins/SetGoal
Topic:
Value: /goal_pose
Views:
Current:
Class: rviz_default_plugins/Orbit
Distance: 5.0
Focal Point:
X: 0.0
Y: 0.0
Z: 0.5
Name: Current View
Pitch: 0.8
Yaw: 2.8

View File

@@ -0,0 +1,84 @@
Panels:
- Class: rviz_common/Displays
Name: Displays
- Class: rviz_common/Views
Name: Views
Visualization Manager:
Class: ""
Displays:
- Alpha: 0.8
Class: rviz_default_plugins/RobotModel
Enabled: true
Name: RobotModel
Robot Description: robot_description
Visual Enabled: true
- Class: rviz_default_plugins/TF
Enabled: true
Name: TF
Frame Timeout: 15
Marker Scale: 0.3
- Class: rviz_default_plugins/Map
Enabled: true
Name: Map
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /map
Update Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /map_updates
Color Scheme: map
Draw Behind: true
Use Timestamp: false
- Class: rviz_default_plugins/LaserScan
Enabled: true
Name: LaserScan
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Best Effort
Value: /scan
Size (m): 0.02
Style: Flat Squares
Decay Time: 0.3
Color Transformer: Intensity
- Class: rviz_default_plugins/Path
Enabled: true
Name: Path (SLAM)
Topic:
Depth: 1
History Policy: Keep Last
Reliability Policy: Reliable
Value: /plan
Color: 25; 255; 0
Line Style: Dashed
Enabled: true
Global Options:
Background Color: 48; 48; 48
Fixed Frame: map
Frame Rate: 30
Name: root
Tools:
- Class: rviz_default_plugins/Interact
- Class: rviz_default_plugins/MoveCamera
- Class: rviz_default_plugins/Select
- Class: rviz_default_plugins/SetInitialPose
Topic:
Value: /initialpose
- Class: rviz_default_plugins/SetGoal
Topic:
Value: /goal_pose
Views:
Current:
Class: rviz_default_plugins/Orbit
Distance: 5.0
Focal Point:
X: 0.0
Y: 0.0
Z: 0.5
Name: Current View
Pitch: 0.8
Yaw: 2.8

View File

@@ -0,0 +1,12 @@
Metadata-Version: 2.1
Name: gc-navigation
Version: 0.0.0
Summary: TODO: Package description
Home-page: UNKNOWN
Maintainer: guoch
Maintainer-email: guoch@todo.todo
License: TODO: License declaration
Platform: UNKNOWN
UNKNOWN

View File

@@ -0,0 +1,15 @@
package.xml
setup.cfg
setup.py
../../build/gc_navigation/gc_navigation.egg-info/PKG-INFO
../../build/gc_navigation/gc_navigation.egg-info/SOURCES.txt
../../build/gc_navigation/gc_navigation.egg-info/dependency_links.txt
../../build/gc_navigation/gc_navigation.egg-info/entry_points.txt
../../build/gc_navigation/gc_navigation.egg-info/requires.txt
../../build/gc_navigation/gc_navigation.egg-info/top_level.txt
../../build/gc_navigation/gc_navigation.egg-info/zip-safe
gc_navigation/__init__.py
resource/gc_navigation
test/test_copyright.py
test/test_flake8.py
test/test_pep257.py

View File

@@ -0,0 +1 @@
prepend-non-duplicate;AMENT_PREFIX_PATH;

View File

@@ -0,0 +1,3 @@
# generated from colcon_powershell/shell/template/hook_prepend_value.ps1.em
colcon_prepend_unique_value AMENT_PREFIX_PATH "$env:COLCON_CURRENT_PREFIX"

View File

@@ -0,0 +1,3 @@
# generated from colcon_core/shell/template/hook_prepend_value.sh.em
_colcon_prepend_unique_value AMENT_PREFIX_PATH "$COLCON_CURRENT_PREFIX"

View File

@@ -0,0 +1 @@
prepend-non-duplicate;PYTHONPATH;lib/python3.10/site-packages

View File

@@ -0,0 +1,3 @@
# generated from colcon_powershell/shell/template/hook_prepend_value.ps1.em
colcon_prepend_unique_value PYTHONPATH "$env:COLCON_CURRENT_PREFIX\lib/python3.10/site-packages"

View File

@@ -0,0 +1,3 @@
# generated from colcon_core/shell/template/hook_prepend_value.sh.em
_colcon_prepend_unique_value PYTHONPATH "$COLCON_CURRENT_PREFIX/lib/python3.10/site-packages"

View File

@@ -0,0 +1,31 @@
# generated from colcon_bash/shell/template/package.bash.em
# This script extends the environment for this package.
# a bash script is able to determine its own path if necessary
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
# the prefix is two levels up from the package specific share directory
_colcon_package_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`/../.." > /dev/null && pwd)"
else
_colcon_package_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
fi
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
_colcon_package_bash_source_script() {
if [ -f "$1" ]; then
if [ -n "$COLCON_TRACE" ]; then
echo "# . \"$1\""
fi
. "$@"
else
echo "not found: \"$1\"" 1>&2
fi
}
# source sh script of this package
_colcon_package_bash_source_script "$_colcon_package_bash_COLCON_CURRENT_PREFIX/share/gc_navigation/package.sh"
unset _colcon_package_bash_source_script
unset _colcon_package_bash_COLCON_CURRENT_PREFIX

View File

@@ -0,0 +1,6 @@
source;share/gc_navigation/hook/pythonpath.ps1
source;share/gc_navigation/hook/pythonpath.dsv
source;share/gc_navigation/hook/pythonpath.sh
source;share/gc_navigation/hook/ament_prefix_path.ps1
source;share/gc_navigation/hook/ament_prefix_path.dsv
source;share/gc_navigation/hook/ament_prefix_path.sh

View File

@@ -0,0 +1,116 @@
# generated from colcon_powershell/shell/template/package.ps1.em
# function to append a value to a variable
# which uses colons as separators
# duplicates as well as leading separators are avoided
# first argument: the name of the result variable
# second argument: the value to be prepended
function colcon_append_unique_value {
param (
$_listname,
$_value
)
# get values from variable
if (Test-Path Env:$_listname) {
$_values=(Get-Item env:$_listname).Value
} else {
$_values=""
}
$_duplicate=""
# start with no values
$_all_values=""
# iterate over existing values in the variable
if ($_values) {
$_values.Split(";") | ForEach {
# not an empty string
if ($_) {
# not a duplicate of _value
if ($_ -eq $_value) {
$_duplicate="1"
}
if ($_all_values) {
$_all_values="${_all_values};$_"
} else {
$_all_values="$_"
}
}
}
}
# append only non-duplicates
if (!$_duplicate) {
# avoid leading separator
if ($_all_values) {
$_all_values="${_all_values};${_value}"
} else {
$_all_values="${_value}"
}
}
# export the updated variable
Set-Item env:\$_listname -Value "$_all_values"
}
# 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
function colcon_prepend_unique_value {
param (
$_listname,
$_value
)
# get values from variable
if (Test-Path Env:$_listname) {
$_values=(Get-Item env:$_listname).Value
} else {
$_values=""
}
# start with the new value
$_all_values="$_value"
# iterate over existing values in the variable
if ($_values) {
$_values.Split(";") | ForEach {
# not an empty string
if ($_) {
# not a duplicate of _value
if ($_ -ne $_value) {
# keep non-duplicate values
$_all_values="${_all_values};$_"
}
}
}
}
# export the updated variable
Set-Item env:\$_listname -Value "$_all_values"
}
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
function colcon_package_source_powershell_script {
param (
$_colcon_package_source_powershell_script
)
# source script with conditional trace output
if (Test-Path $_colcon_package_source_powershell_script) {
if ($env:COLCON_TRACE) {
echo ". '$_colcon_package_source_powershell_script'"
}
. "$_colcon_package_source_powershell_script"
} else {
Write-Error "not found: '$_colcon_package_source_powershell_script'"
}
}
# a powershell script is able to determine its own path
# the prefix is two levels up from the package specific share directory
$env:COLCON_CURRENT_PREFIX=(Get-Item $PSCommandPath).Directory.Parent.Parent.FullName
colcon_package_source_powershell_script "$env:COLCON_CURRENT_PREFIX\share/gc_navigation/hook/pythonpath.ps1"
colcon_package_source_powershell_script "$env:COLCON_CURRENT_PREFIX\share/gc_navigation/hook/ament_prefix_path.ps1"
Remove-Item Env:\COLCON_CURRENT_PREFIX

View File

@@ -0,0 +1,87 @@
# generated from colcon_core/shell/template/package.sh.em
# This script extends the environment for this package.
# 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_prepend_unique_value() {
# arguments
_listname="$1"
_value="$2"
# get values from variable
eval _values=\"\$$_listname\"
# backup the field separator
_colcon_prepend_unique_value_IFS=$IFS
IFS=":"
# start with the new value
_all_values="$_value"
# workaround SH_WORD_SPLIT not being set in zsh
if [ "$(command -v colcon_zsh_convert_to_array)" ]; then
colcon_zsh_convert_to_array _values
fi
# 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
continue
fi
# keep non-duplicate values
_all_values="$_all_values:$_item"
done
unset _item
# restore the field separator
IFS=$_colcon_prepend_unique_value_IFS
unset _colcon_prepend_unique_value_IFS
# export the updated variable
eval export $_listname=\"$_all_values\"
unset _all_values
unset _values
unset _value
unset _listname
}
# 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_package_sh_COLCON_CURRENT_PREFIX="/home/guoch/test_ws/install/gc_navigation"
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
if [ ! -d "$_colcon_package_sh_COLCON_CURRENT_PREFIX" ]; then
echo "The build time path \"$_colcon_package_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_package_sh_COLCON_CURRENT_PREFIX
return 1
fi
COLCON_CURRENT_PREFIX="$_colcon_package_sh_COLCON_CURRENT_PREFIX"
fi
unset _colcon_package_sh_COLCON_CURRENT_PREFIX
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
_colcon_package_sh_source_script() {
if [ -f "$1" ]; then
if [ -n "$COLCON_TRACE" ]; then
echo "# . \"$1\""
fi
. "$@"
else
echo "not found: \"$1\"" 1>&2
fi
}
# source sh hooks
_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/gc_navigation/hook/pythonpath.sh"
_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/gc_navigation/hook/ament_prefix_path.sh"
unset _colcon_package_sh_source_script
unset COLCON_CURRENT_PREFIX
# do not unset _colcon_prepend_unique_value since it might be used by non-primary shell hooks

View File

@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>gc_navigation</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="guoch@todo.todo">guoch</maintainer>
<license>TODO: License declaration</license>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>

View File

@@ -0,0 +1,42 @@
# generated from colcon_zsh/shell/template/package.zsh.em
# This script extends the environment for this package.
# a zsh script is able to determine its own path if necessary
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
# the prefix is two levels up from the package specific share directory
_colcon_package_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`/../.." > /dev/null && pwd)"
else
_colcon_package_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
fi
# function to source another script with conditional trace output
# first argument: the path of the script
# additional arguments: arguments to the script
_colcon_package_zsh_source_script() {
if [ -f "$1" ]; then
if [ -n "$COLCON_TRACE" ]; then
echo "# . \"$1\""
fi
. "$@"
else
echo "not found: \"$1\"" 1>&2
fi
}
# function to convert array-like strings into arrays
# to workaround SH_WORD_SPLIT not being set
colcon_zsh_convert_to_array() {
local _listname=$1
local _dollar="$"
local _split="{="
local _to_array="(\"$_dollar$_split$_listname}\")"
eval $_listname=$_to_array
}
# source sh script of this package
_colcon_package_zsh_source_script "$_colcon_package_zsh_COLCON_CURRENT_PREFIX/share/gc_navigation/package.sh"
unset convert_zsh_to_array
unset _colcon_package_zsh_source_script
unset _colcon_package_zsh_COLCON_CURRENT_PREFIX

View File

@@ -0,0 +1 @@
/home/guoch/test_ws/install/origincar_description:/home/guoch/test_ws/install/gc_slamtoolbox:/home/guoch/test_ws/install/gc_slam_toolbox_fish:/home/guoch/test_ws/install/gc_navigation_fish:/home/guoch/test_ws/install/gc_navigation2_slamtoolbox:/home/guoch/test_ws/install/gc_navigation:/home/guoch/robot_ws/install/my_robot_description:/opt/ros/humble

View File

@@ -0,0 +1,14 @@
# generated from ament/cmake/core/templates/nameConfig-version.cmake.in
set(PACKAGE_VERSION "0.0.0")
set(PACKAGE_VERSION_EXACT False)
set(PACKAGE_VERSION_COMPATIBLE False)
if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}")
set(PACKAGE_VERSION_EXACT True)
set(PACKAGE_VERSION_COMPATIBLE True)
endif()
if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE True)
endif()

View File

@@ -0,0 +1,42 @@
# generated from ament/cmake/core/templates/nameConfig.cmake.in
# prevent multiple inclusion
if(_gc_navigation2_slamtoolbox_CONFIG_INCLUDED)
# ensure to keep the found flag the same
if(NOT DEFINED gc_navigation2_slamtoolbox_FOUND)
# explicitly set it to FALSE, otherwise CMake will set it to TRUE
set(gc_navigation2_slamtoolbox_FOUND FALSE)
elseif(NOT gc_navigation2_slamtoolbox_FOUND)
# use separate condition to avoid uninitialized variable warning
set(gc_navigation2_slamtoolbox_FOUND FALSE)
endif()
return()
endif()
set(_gc_navigation2_slamtoolbox_CONFIG_INCLUDED TRUE)
# output package information
if(NOT gc_navigation2_slamtoolbox_FIND_QUIETLY)
message(STATUS "Found gc_navigation2_slamtoolbox: 0.0.0 (${gc_navigation2_slamtoolbox_DIR})")
endif()
# warn when using a deprecated package
if(NOT "" STREQUAL "")
set(_msg "Package 'gc_navigation2_slamtoolbox' is deprecated")
# append custom deprecation text if available
if(NOT "" STREQUAL "TRUE")
set(_msg "${_msg} ()")
endif()
# optionally quiet the deprecation message
if(NOT ${gc_navigation2_slamtoolbox_DEPRECATED_QUIET})
message(DEPRECATION "${_msg}")
endif()
endif()
# flag package as ament-based to distinguish it after being find_package()-ed
set(gc_navigation2_slamtoolbox_FOUND_AMENT_PACKAGE TRUE)
# include all config extra files
set(_extras "")
foreach(_extra ${_extras})
include("${gc_navigation2_slamtoolbox_DIR}/${_extra}")
endforeach()

View File

@@ -0,0 +1,89 @@
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_link
scan_topic: /scan
use_map_saver: true
mode: mapping
# lifelong params
lifelong_search_use_tree: false
lifelong_minimum_score: 0.1
lifelong_iou_match: 0.85
lifelong_node_removal_score: 0.04
lifelong_overlap_score_scale: 0.06
lifelong_constraint_multiplier: 0.08
lifelong_nearby_penalty: 0.001
lifelong_candidates_scale: 0.03
# 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: test_steve
#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
restamp_tf: false
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: 10.
stack_size_to_use: 40000000 #// program needs a larger stack size to serialize large maps
# General Parameters
use_scan_matching: true
use_scan_barycenter: true
minimum_travel_distance: 0.5
minimum_travel_heading: 0.5
check_min_dist_and_heading_precisely: false
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

View File

@@ -0,0 +1,72 @@
slam_toolbox:
ros__parameters:
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_link
scan_topic: /scan
mode: localization #localization
# if you'd like to start localizing on bringup in a map and pose
# map_file_name: /home/guoch/test_ws/src/gc_navigation2_slamtoolbox/maps/my_map.posegraph
# map_start_pose: [0.0, 0.0, 0.0]
debug_logging: false
throttle_scans: 1
transform_publish_period: 0.02 #if 0 never publishes odometry
map_update_interval: 5.0
resolution: 0.05
restamp_tf: false
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
# General Parameters
use_scan_matching: true
use_scan_barycenter: true
minimum_travel_distance: 0.5
minimum_travel_heading: 0.5
check_min_dist_and_heading_precisely: false
scan_buffer_size: 3
scan_buffer_maximum_scan_distance: 10.0
link_match_minimum_response_fine: 0.1
link_scan_maximum_distance: 1.5
do_loop_closing: true
loop_match_minimum_chain_size: 3
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
loop_search_maximum_distance: 3.0
# 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

View File

@@ -0,0 +1,71 @@
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: mapping #localization
debug_logging: false
throttle_scans: 1
transform_publish_period: 0.02 #if 0 never publishes odometry
map_update_interval: 10.0
resolution: 0.05
restamp_tf: false
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: 14400.
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.5
minimum_travel_heading: 0.5
check_min_dist_and_heading_precisely: false
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

View File

@@ -0,0 +1,79 @@
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 #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/guoch/test_ws/src/gc_navigation2_slamtoolbox/maps/my_map.posegraph
# 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
restamp_tf: false
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.0
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.5
minimum_travel_heading: 0.5
check_min_dist_and_heading_precisely: false
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

View File

@@ -0,0 +1,74 @@
$(var namespace)/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: global_odom
map_frame: map
base_frame: base_footprint
scan_topic: scan
mode: mapping #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: test_steve
# 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
max_laser_range: 20.0 #for rastering images
minimum_time_interval: 0.5
transform_timeout: 0.2
tf_buffer_duration: 30.0
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.5
minimum_travel_heading: 0.5
check_min_dist_and_heading_precisely: false
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

View File

@@ -0,0 +1,79 @@
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: mapping #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: test_steve
#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
restamp_tf: false
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.5
minimum_travel_heading: 0.5
check_min_dist_and_heading_precisely: false
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

View File

@@ -0,0 +1,137 @@
Panels:
- Class: rviz_common/Displays
Help Height: 78
Name: Displays
Property Tree Widget:
Expanded:
- /Global Options1
- /Status1
Splitter Ratio: 0.5
Tree Height: 154
- 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: ""
- 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: <Fixed Frame>
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: 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.785398006439209
Target Frame: <Fixed Frame>
Value: Orbit (rviz)
Yaw: 0.785398006439209
Saved: ~
Window Geometry:
Displays:
collapsed: false
Height: 846
Hide Left Dock: false
Hide Right Dock: false
QMainWindow State: 000000ff00000000fd000000040000000000000217000002b0fc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000125000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb000000220053006c0061006d0054006f006f006c0062006f00780050006c007500670069006e0100000168000001850000018500ffffff000000010000010f000002b0fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d000002b0000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004b00000003efc0100000002fb0000000800540069006d00650100000000000004b0000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000017e000002b000000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
Selection:
collapsed: false
SlamToolboxPlugin:
collapsed: false
Time:
collapsed: false
Tool Properties:
collapsed: false
Views:
collapsed: false
Width: 1200
X: 72
Y: 60

View File

@@ -0,0 +1,55 @@
slam_toolbox:
ros__parameters:
# 核心模式设置
use_sim_time: true
mode: "localization" # 重要:设置为定位模式
map_file_name: "" # 由启动参数传入
map_start_pose: [0.0,0.0,0.0]
# ROS框架设置
odom_frame: "odom"
map_frame: "map"
base_frame: "base_footprint"
scan_topic: "/scan"
# 求解器设置
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"
# 定位优化参数
use_scan_matching: true
use_scan_barycenter: true
minimum_travel_distance: 0.05
minimum_travel_heading: 0.087
# 扫描处理
scan_buffer_size: 50
throttle_scans: 2
# 回环检测(定位模式可关闭)
do_loop_closing: false
# 搜索参数
link_match_minimum_response_fine: 0.2
link_scan_maximum_distance: 2.0
loop_search_maximum_distance: 5.0
# 性能参数
minimum_time_interval: 0.1
transform_publish_period: 0.02
map_update_interval: 0.5
# 地图参数
resolution: 0.05
max_laser_range: 15.0
min_laser_range: 0.2
# 初始位姿可选可以通过RViz设置
# map_start_pose: [0.0, 0.0, 0.0]
# 调试
debug_logging: false
enable_interactive_mode: true

View File

@@ -0,0 +1 @@
prepend-non-duplicate;AMENT_PREFIX_PATH;

View File

@@ -0,0 +1,4 @@
# copied from
# ament_cmake_core/cmake/environment_hooks/environment/ament_prefix_path.sh
ament_prepend_unique_value AMENT_PREFIX_PATH "$AMENT_CURRENT_PREFIX"

View File

@@ -0,0 +1 @@
prepend-non-duplicate-if-exists;PATH;bin

View File

@@ -0,0 +1,5 @@
# copied from ament_cmake_core/cmake/environment_hooks/environment/path.sh
if [ -d "$AMENT_CURRENT_PREFIX/bin" ]; then
ament_prepend_unique_value PATH "$AMENT_CURRENT_PREFIX/bin"
fi

View File

@@ -0,0 +1 @@
prepend-non-duplicate;CMAKE_PREFIX_PATH;

View File

@@ -0,0 +1,3 @@
# generated from colcon_powershell/shell/template/hook_prepend_value.ps1.em
colcon_prepend_unique_value CMAKE_PREFIX_PATH "$env:COLCON_CURRENT_PREFIX"

View File

@@ -0,0 +1,3 @@
# generated from colcon_core/shell/template/hook_prepend_value.sh.em
_colcon_prepend_unique_value CMAKE_PREFIX_PATH "$COLCON_CURRENT_PREFIX"

View File

@@ -0,0 +1,170 @@
from launch.actions import IncludeLaunchDescription
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription, DeclareLaunchArgument, TimerAction
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
# def generate_launch_description():
# # 获取包路径
# gc_navigation2_dir = get_package_share_directory(
# 'gc_navigation2_slamtoolbox')
# nav2_bringup_dir = get_package_share_directory('nav2_bringup')
# # 声明参数
# use_sim_time = LaunchConfiguration('use_sim_time', default='True')
# slam = LaunchConfiguration('slam', default='True')
# localization = LaunchConfiguration('localization', default='True')
# # 定义文件路径
# map_yaml_path = os.path.join(gc_navigation2_dir, 'maps', 'my_map.yaml')
# nav2_param_path = os.path.join(
# gc_navigation2_dir, 'params', 'gc_navigation.yaml')
# slam_params_file = os.path.join(
# gc_navigation2_dir, 'config', 'slam_toolbox_localization.yaml')
# # 定义地图基础路径(用于 .posegraph 文件)
# map_base_path = os.path.join(gc_navigation2_dir, 'maps', 'my_map')
# # 检查 .posegraph 文件是否存在
# posegraph_path = map_base_path + '.posegraph'
# if not os.path.exists(posegraph_path):
# print(f"警告: .posegraph 文件不存在: {posegraph_path}")
# print("将使用 AMCL 替代")
# use_slam_toolbox = False
# else:
# use_slam_toolbox = True
# print(f"找到 .posegraph 文件: {posegraph_path}")
# # 创建启动描述
# ld = LaunchDescription([
# DeclareLaunchArgument('use_sim_time', default_value='True'),
# DeclareLaunchArgument('slam', default_value='True'),
# DeclareLaunchArgument('localization', default_value='True'),
# ])
# # 如果使用 slam_toolbox
# if use_slam_toolbox:
# slam_toolbox_node = Node(
# package='slam_toolbox',
# executable='localization_slam_toolbox_node',
# name='slam_toolbox',
# output='screen',
# parameters=[
# slam_params_file,
# {'map_file_name': map_base_path}
# ]
# )
# ld.add_action(slam_toolbox_node)
# # 使用 slam_toolbox 时Nav2 不启用定位
# localization_arg = 'False'
# print("slam成功配置")
# ld.add_action(TimerAction(
# period=1.5,
# actions=[]
# ))
# else:
# # 使用 AMCL
# localization_arg = 'True'
# # Nav2 启动 - 使用正确的路径
# nav2_launch_path = os.path.join(
# nav2_bringup_dir, 'launch', 'bringup_launch.py')
# if not os.path.exists(nav2_launch_path):
# print(f"错误: 找不到 Nav2 启动文件: {nav2_launch_path}")
# return ld
# else:
# print("nav2桥通过")
# nav2_bringup_launch = IncludeLaunchDescription(
# PythonLaunchDescriptionSource(nav2_launch_path),
# launch_arguments={
# 'map': map_yaml_path,
# 'use_sim_time': use_sim_time,
# 'params_file': nav2_param_path,
# 'slam': slam,
# 'localization': localization_arg,
# 'autostart': 'True',
# }.items(),
# )
# print("结束配置")
# ld.add_action(nav2_bringup_launch)
# return ld
# def generate_launch_description():
# ld = LaunchDescription()
# # 获取参数文件路径
# slam_pkg_share = get_package_share_directory('gc_navigation2_slamtoolbox')
# slam_file = os.path.join(
# slam_pkg_share, 'config', 'slam_toolbox_localization.yaml')
# use_sim_time = LaunchConfiguration('use_sim_time', default='true')
# map_base_path = os.path.join(slam_pkg_share, 'maps', 'my_map')
# posegraph_path = map_base_path+'.posegraph'
# # 创建SLAM Toolbox节点
# slam_toolbox_node = Node(
# package='slam_toolbox',
# executable='async_slam_toolbox_node', # 或 sync_slam_toolbox_node
# name='slam_toolbox',
# output='screen',
# parameters=[slam_file,
# {
# 'map_file_name': map_base_path,
# 'use_sim_time': use_sim_time
# }]
# )
# # ld.add_action(slam_toolbox_node)
# nav2_bringup_dir = get_package_share_directory('nav2_bringup')
# nav_pkg = get_package_share_directory(
# 'gc_navigation2_slamtoolbox')
# map_yaml_path = LaunchConfiguration('map', default=os.path.join(
# nav_pkg, 'maps', 'my_map.yaml'))
# nav2_param_path = LaunchConfiguration('params_file', default=os.path.join(
# nav_pkg, 'params', 'gc_navigation.yaml'))
# nav2_bringup_launch = IncludeLaunchDescription(
# PythonLaunchDescriptionSource(
# [nav2_bringup_dir, '/launch', '/bringup_launch.py']),
# launch_arguments={
# 'map': map_yaml_path,
# 'use_sim_time': use_sim_time,
# 'params_file': nav2_param_path}.items(),
# )
# time=TimerAction(period=2.0,
# actions=[])
# ld.add_action(time)
# ld.add_action(nav2_bringup_launch)
# return ld
def generate_launch_description():
# =============================1.定位到包的地址=============================================================
gc_navigation_fish_dir = get_package_share_directory(
'gc_navigation2_slamtoolbox')
nav2_bringup_dir = get_package_share_directory('nav2_bringup')
# =============================2.声明参数,获取配置文件路径===================================================
# use_sim_time 这里要设置成true,因为gazebo是仿真环境其时间是通过/clock话题获取而不是系统时间
use_sim_time = LaunchConfiguration('use_sim_time', default='true')
map_yaml_path = LaunchConfiguration('map', default=os.path.join(
gc_navigation_fish_dir, 'maps', 'my_map.yaml'))
nav2_param_path = LaunchConfiguration('params_file', default=os.path.join(
gc_navigation_fish_dir, 'params', 'gc_navigation.yaml'))
# =============================3.声明启动launch文件传入地图路径、是否使用仿真时间以及nav2参数文件==============
nav2_bringup_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[nav2_bringup_dir, '/launch', '/bringup_launch.py']),
launch_arguments={
'map': map_yaml_path,
'use_sim_time': use_sim_time,
'params_file': nav2_param_path}.items(),
)
return LaunchDescription([nav2_bringup_launch])

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python3
from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os
def generate_launch_description():
# 获取参数文件路径
pkg_share = get_package_share_directory('gc_navigation2_slamtoolbox')
params_file = os.path.join(
pkg_share, 'config', 'mapper_params_lifelong.yaml')
# 创建SLAM Toolbox节点
slam_toolbox_node = Node(
package='slam_toolbox',
executable='async_slam_toolbox_node', # 或 sync_slam_toolbox_node
name='slam_toolbox',
output='screen',
parameters=[params_file]
)
return LaunchDescription([
slam_toolbox_node
])

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python3
from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os
def generate_launch_description():
# 获取参数文件路径
pkg_share = get_package_share_directory('gc_navigation2_slamtoolbox')
params_file = os.path.join(
pkg_share, 'config', 'mapper_params_localization.yaml')
# 创建SLAM Toolbox节点
slam_toolbox_node = Node(
package='slam_toolbox',
executable='localization_slam_toolbox_node', # 或 sync_slam_toolbox_node
name='slam_toolbox',
output='screen',
parameters=[params_file]
)
return LaunchDescription([
slam_toolbox_node
])

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python3
from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os
def generate_launch_description():
# 获取参数文件路径
pkg_share = get_package_share_directory('gc_navigation2_slamtoolbox')
params_file = os.path.join(
pkg_share, 'config', 'mapper_params_online_async.yaml')
# 创建SLAM Toolbox节点
slam_toolbox_node = Node(
package='slam_toolbox',
executable='async_slam_toolbox_node', # 或 sync_slam_toolbox_node
name='slam_toolbox',
output='screen',
parameters=[params_file]
)
return LaunchDescription([
slam_toolbox_node
])

View File

@@ -0,0 +1,46 @@
# generated from ament_package/template/package_level/local_setup.bash.in
# source local_setup.sh from same directory as this file
_this_path=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" && pwd)
# provide AMENT_CURRENT_PREFIX to shell script
AMENT_CURRENT_PREFIX=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`/../.." && pwd)
# store AMENT_CURRENT_PREFIX to restore it before each environment hook
_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX
# trace output
if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
echo "# . \"$_this_path/local_setup.sh\""
fi
. "$_this_path/local_setup.sh"
unset _this_path
# unset AMENT_ENVIRONMENT_HOOKS
# if not appending to them for return
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
unset AMENT_ENVIRONMENT_HOOKS
fi
# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# list all environment hooks of this package
# source all shell-specific environment hooks of this package
# if not returning them
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
_package_local_setup_IFS=$IFS
IFS=":"
for _hook in $AMENT_ENVIRONMENT_HOOKS; do
# restore AMENT_CURRENT_PREFIX for each environment hook
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# restore IFS before sourcing other files
IFS=$_package_local_setup_IFS
. "$_hook"
done
unset _hook
IFS=$_package_local_setup_IFS
unset _package_local_setup_IFS
unset AMENT_ENVIRONMENT_HOOKS
fi
unset _package_local_setup_AMENT_CURRENT_PREFIX
unset AMENT_CURRENT_PREFIX

View File

@@ -0,0 +1,2 @@
source;share/gc_navigation2_slamtoolbox/environment/ament_prefix_path.sh
source;share/gc_navigation2_slamtoolbox/environment/path.sh

View File

@@ -0,0 +1,184 @@
# generated from ament_package/template/package_level/local_setup.sh.in
# since this file is sourced use either the provided AMENT_CURRENT_PREFIX
# or fall back to the destination set at configure time
: ${AMENT_CURRENT_PREFIX:="/home/guoch/test_ws/install/gc_navigation2_slamtoolbox"}
if [ ! -d "$AMENT_CURRENT_PREFIX" ]; then
if [ -z "$COLCON_CURRENT_PREFIX" ]; then
echo "The compile time prefix path '$AMENT_CURRENT_PREFIX' doesn't " \
"exist. Consider sourcing a different extension than '.sh'." 1>&2
else
AMENT_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
fi
fi
# function to append values to environment variables
# using colons as separators and avoiding leading separators
ament_append_value() {
# arguments
_listname="$1"
_value="$2"
#echo "listname $_listname"
#eval echo "list value \$$_listname"
#echo "value $_value"
# avoid leading separator
eval _values=\"\$$_listname\"
if [ -z "$_values" ]; then
eval export $_listname=\"$_value\"
#eval echo "set list \$$_listname"
else
# field separator must not be a colon
_ament_append_value_IFS=$IFS
unset IFS
eval export $_listname=\"\$$_listname:$_value\"
#eval echo "append list \$$_listname"
IFS=$_ament_append_value_IFS
unset _ament_append_value_IFS
fi
unset _values
unset _value
unset _listname
}
# function to append non-duplicate values to environment variables
# using colons as separators and avoiding leading separators
ament_append_unique_value() {
# arguments
_listname=$1
_value=$2
#echo "listname $_listname"
#eval echo "list value \$$_listname"
#echo "value $_value"
# check if the list contains the value
eval _values=\$$_listname
_duplicate=
_ament_append_unique_value_IFS=$IFS
IFS=":"
if [ "$AMENT_SHELL" = "zsh" ]; then
ament_zsh_to_array _values
fi
for _item in $_values; do
# ignore empty strings
if [ -z "$_item" ]; then
continue
fi
if [ $_item = $_value ]; then
_duplicate=1
fi
done
unset _item
# append only non-duplicates
if [ -z "$_duplicate" ]; then
# avoid leading separator
if [ -z "$_values" ]; then
eval $_listname=\"$_value\"
#eval echo "set list \$$_listname"
else
# field separator must not be a colon
unset IFS
eval $_listname=\"\$$_listname:$_value\"
#eval echo "append list \$$_listname"
fi
fi
IFS=$_ament_append_unique_value_IFS
unset _ament_append_unique_value_IFS
unset _duplicate
unset _values
unset _value
unset _listname
}
# function to prepend non-duplicate values to environment variables
# using colons as separators and avoiding trailing separators
ament_prepend_unique_value() {
# arguments
_listname="$1"
_value="$2"
#echo "listname $_listname"
#eval echo "list value \$$_listname"
#echo "value $_value"
# check if the list contains the value
eval _values=\"\$$_listname\"
_duplicate=
_ament_prepend_unique_value_IFS=$IFS
IFS=":"
if [ "$AMENT_SHELL" = "zsh" ]; then
ament_zsh_to_array _values
fi
for _item in $_values; do
# ignore empty strings
if [ -z "$_item" ]; then
continue
fi
if [ "$_item" = "$_value" ]; then
_duplicate=1
fi
done
unset _item
# prepend only non-duplicates
if [ -z "$_duplicate" ]; then
# avoid trailing separator
if [ -z "$_values" ]; then
eval export $_listname=\"$_value\"
#eval echo "set list \$$_listname"
else
# field separator must not be a colon
unset IFS
eval export $_listname=\"$_value:\$$_listname\"
#eval echo "prepend list \$$_listname"
fi
fi
IFS=$_ament_prepend_unique_value_IFS
unset _ament_prepend_unique_value_IFS
unset _duplicate
unset _values
unset _value
unset _listname
}
# unset AMENT_ENVIRONMENT_HOOKS
# if not appending to them for return
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
unset AMENT_ENVIRONMENT_HOOKS
fi
# list all environment hooks of this package
ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/gc_navigation2_slamtoolbox/environment/ament_prefix_path.sh"
ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/gc_navigation2_slamtoolbox/environment/path.sh"
# source all shell-specific environment hooks of this package
# if not returning them
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
_package_local_setup_IFS=$IFS
IFS=":"
if [ "$AMENT_SHELL" = "zsh" ]; then
ament_zsh_to_array AMENT_ENVIRONMENT_HOOKS
fi
for _hook in $AMENT_ENVIRONMENT_HOOKS; do
if [ -f "$_hook" ]; then
# restore IFS before sourcing other files
IFS=$_package_local_setup_IFS
# trace output
if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
echo "# . \"$_hook\""
fi
. "$_hook"
fi
done
unset _hook
IFS=$_package_local_setup_IFS
unset _package_local_setup_IFS
unset AMENT_ENVIRONMENT_HOOKS
fi
# reset AMENT_CURRENT_PREFIX after each package
# allowing to source multiple package-level setup files
unset AMENT_CURRENT_PREFIX

View File

@@ -0,0 +1,59 @@
# generated from ament_package/template/package_level/local_setup.zsh.in
AMENT_SHELL=zsh
# source local_setup.sh from same directory as this file
_this_path=$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)
# provide AMENT_CURRENT_PREFIX to shell script
AMENT_CURRENT_PREFIX=$(builtin cd -q "`dirname "${(%):-%N}"`/../.." > /dev/null && pwd)
# store AMENT_CURRENT_PREFIX to restore it before each environment hook
_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX
# function to convert array-like strings into arrays
# to wordaround SH_WORD_SPLIT not being set
ament_zsh_to_array() {
local _listname=$1
local _dollar="$"
local _split="{="
local _to_array="(\"$_dollar$_split$_listname}\")"
eval $_listname=$_to_array
}
# trace output
if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
echo "# . \"$_this_path/local_setup.sh\""
fi
# the package-level local_setup file unsets AMENT_CURRENT_PREFIX
. "$_this_path/local_setup.sh"
unset _this_path
# unset AMENT_ENVIRONMENT_HOOKS
# if not appending to them for return
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
unset AMENT_ENVIRONMENT_HOOKS
fi
# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# list all environment hooks of this package
# source all shell-specific environment hooks of this package
# if not returning them
if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
_package_local_setup_IFS=$IFS
IFS=":"
for _hook in $AMENT_ENVIRONMENT_HOOKS; do
# restore AMENT_CURRENT_PREFIX for each environment hook
AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
# restore IFS before sourcing other files
IFS=$_package_local_setup_IFS
. "$_hook"
done
unset _hook
IFS=$_package_local_setup_IFS
unset _package_local_setup_IFS
unset AMENT_ENVIRONMENT_HOOKS
fi
unset _package_local_setup_AMENT_CURRENT_PREFIX
unset AMENT_CURRENT_PREFIX

View File

@@ -0,0 +1,7 @@
image: map_1770592084.pgm
mode: trinary
resolution: 0.05
origin: [-2.15, -5.81, 0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.25

Some files were not shown because too many files have changed in this diff Show More