mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-12 04:29:49 +08:00
Merge branch 'ros2' of github.com:introlab/rtabmap_ros into rolling-devel
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
+ [Turtlebot3 Nav2 and RGB-D SLAM](#turtlebot3-nav2-and-rgb-d-slam)
|
||||
+ [Turtlebot3 Nav2, 2D LiDAR and RGB-D SLAM](#turtlebot3-nav2-2d-lidar-and-rgb-d-slam)
|
||||
+ [Turtlebot3 Nav2, Fake 2D LiDAR and RGB-D SLAM](#turtlebot3-nav2-fake-2d-lidar-and-rgb-d-slam)
|
||||
+ [Turtlebot3 Nav2, 2D LiDAR SLAM with FusionCore (IMU + wheel UKF)](#turtlebot3-nav2-2d-lidar-slam-with-fusioncore-imu--wheel-ukf)
|
||||
+ [Champ Quadruped Nav2, Elevation Map and VSLAM](#champ-quadruped-nav2-elevation-map-and-vslam)
|
||||
+ [Clearpath Husky Nav2, 2D LiDAR and RGB-D SLAM](#clearpath-husky-nav2-2d-lidar-and-rgb-d-slam)
|
||||
+ [Clearpath Husky Nav2, 3D LiDAR and RGB-D SLAM](#clearpath-husky-nav2-3d-lidar-and-rgb-d-slam)
|
||||
@@ -59,6 +60,12 @@
|
||||
* Yellow: The map.
|
||||
|
||||

|
||||
### Turtlebot3 Nav2, 2D LiDAR SLAM with FusionCore (IMU + wheel UKF)
|
||||
[turtlebot3_sim_fusioncore_icp_demo.launch.py](https://github.com/introlab/rtabmap_ros/blob/ros2/rtabmap_demos/launch/turtlebot3/fusioncore/turtlebot3_sim_fusioncore_icp_demo.launch.py) (Jazzy + Gazebo Harmonic)
|
||||
|
||||
FusionCore (wheel + IMU UKF) and `icp_odometry` run in a feedback loop: FusionCore's stable `odom` frame seeds scan matching via `guess_frame_id`, and the ICP result feeds back into FusionCore as a second velocity source. See [README](launch/turtlebot3/fusioncore/README.md) for architecture details.
|
||||
|
||||

|
||||
### Champ Quadruped Nav2, Elevation Map and VSLAM
|
||||
[champ_sim_vslam.launch.py](https://github.com/introlab/rtabmap_ros/blob/ros2/rtabmap_demos/launch/champ/champ_sim_vslam.launch.py)
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ def generate_launch_description():
|
||||
Node(
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
namespace=robot_ns,
|
||||
parameters=[rtabmap_parameters, shared_parameters],
|
||||
parameters=[rtabmap_parameters, shared_parameters,
|
||||
{"odometry_node_name": "icp_odometry"}],
|
||||
remappings=remappings),
|
||||
])
|
||||
|
||||
@@ -141,6 +141,7 @@ def generate_launch_description():
|
||||
Node(
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
namespace=robot_ns,
|
||||
parameters=[rtabmap_parameters, shared_parameters],
|
||||
parameters=[rtabmap_parameters, shared_parameters,
|
||||
{"odometry_node_name": "icp_odometry"}],
|
||||
remappings=remappings),
|
||||
])
|
||||
|
||||
@@ -129,6 +129,7 @@ def generate_launch_description():
|
||||
Node(
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
namespace=robot_ns,
|
||||
parameters=[rtabmap_parameters, shared_parameters],
|
||||
parameters=[rtabmap_parameters, shared_parameters,
|
||||
{"odometry_node_name": "icp_odometry"}],
|
||||
remappings=remappings + [('scan_cloud', 'sensors/lidar3d_0/points')]),
|
||||
])
|
||||
|
||||
@@ -103,7 +103,8 @@ def launch_setup(context, *args, **kwargs):
|
||||
condition=IfCondition(rtabmap_viz),
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
namespace='rtabmap',
|
||||
parameters=[parameters],
|
||||
parameters=[parameters,
|
||||
{"odometry_node_name": vo_node_prefix+'_odometry'}],
|
||||
remappings=remappings),
|
||||
]
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ def generate_launch_description():
|
||||
'Kp/DetectorStrategy': '1', # Referred paper used SURF (0), here use SIFT as it is available with opencv binaries
|
||||
'Vis/FeatureType': '1', # Referred paper used SURF (0), here use SIFT as it is available with opencv binaries
|
||||
'Kp/MaxFeatures': '400',
|
||||
'Kp/BadSignRatio': '0.25', # Kp/BadSignRatio behaves differently than before if Kp/MaxFeatures is not 0, that is now a ratio of Kp/MaxFeatures directly.
|
||||
'Reg/Force3DoF': 'true',
|
||||
'RGBD/OptimizeMaxError': '10',
|
||||
'Optimizer/Strategy': '2', # Referred paper used TORO (0), latest version recommends GTSAM (2)
|
||||
|
||||
@@ -141,7 +141,8 @@ def generate_launch_description():
|
||||
Node(
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
condition=IfCondition(LaunchConfiguration("rtabmap_viz")),
|
||||
parameters=[parameters],
|
||||
parameters=[parameters,
|
||||
{"odometry_node_name": 'stereo_odometry'}],
|
||||
remappings=remappings),
|
||||
Node(
|
||||
package='rviz2', executable='rviz2', name="rviz2", output='screen',
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
# Requirements:
|
||||
# Download one or both rosbags:
|
||||
# * stereo_outdoorA.db3: https://drive.google.com/file/d/1O7mCXg_sw4tZY1S88a-n96O6OulmqvqI/view?usp=drive_link
|
||||
# * stereo_outdoorB.db3: https://drive.google.com/file/d/1mSu7418Fkbe-hIz2-3Mi936PrWuD2un_/view?usp=drive_link
|
||||
#
|
||||
# This is the "composition" variant of stereo_outdoor_demo.launch.py: the whole
|
||||
# pipeline (image_proc rectification, stereo synchronization, visual odometry
|
||||
# and SLAM) runs as composable nodes in a single component container
|
||||
# (rtabmap_container). We can set 'use_intra_process_comms' on all of them.
|
||||
# That way images are passed between rectify -> disparity/sync -> odometry ->
|
||||
# SLAM by pointer, without inter-process serialization/copies.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# SLAM:
|
||||
# $ ros2 launch rtabmap_demos stereo_outdoor_demo_composition.launch.py rviz:=true rtabmap_viz:=true
|
||||
#
|
||||
# Rosbag:
|
||||
# $ ros2 bag play stereo_outdoorA.db3 --clock
|
||||
# when done, you can play the secon bag:
|
||||
# $ ros2 bag play stereo_outdoorB.db3 --clock
|
||||
#
|
||||
|
||||
from launch import LaunchDescription
|
||||
from launch.actions import DeclareLaunchArgument
|
||||
from launch.substitutions import LaunchConfiguration
|
||||
from launch.conditions import IfCondition, UnlessCondition
|
||||
from launch_ros.actions import Node, SetParameter, ComposableNodeContainer, LoadComposableNodes
|
||||
from launch_ros.descriptions import ComposableNode
|
||||
import os
|
||||
from ament_index_python.packages import get_package_share_directory
|
||||
|
||||
def generate_launch_description():
|
||||
|
||||
localization = LaunchConfiguration('localization')
|
||||
|
||||
parameters={
|
||||
'frame_id':'base_footprint',
|
||||
'subscribe_rgbd':True,
|
||||
'approx_sync':False, # odom is generated from images, so we can exactly sync all inputs
|
||||
'map_negative_poses_ignored':True,
|
||||
'subscribe_odom_info': True,
|
||||
# RTAB-Map's internal parameters should be strings
|
||||
'OdomF2M/MaxSize': '1000',
|
||||
'GFTT/MinDistance': '10',
|
||||
'GFTT/QualityLevel': '0.00001',
|
||||
#'Kp/DetectorStrategy': '6', # Uncommment to match ros1 noetic results, but opencv should be built with xfeatures2d
|
||||
#'Vis/FeatureType': '6' # Uncommment to match ros1 noetic results, but opencv should be built with xfeatures2d
|
||||
}
|
||||
|
||||
remappings=[
|
||||
('rgbd_image', '/stereo_camera/rgbd_image'),
|
||||
('odom', '/vo')]
|
||||
|
||||
# Enable zero-copy intra-process communication between all composable nodes
|
||||
# loaded in the container.
|
||||
intra_process = [{'use_intra_process_comms': True}]
|
||||
|
||||
config_rviz = os.path.join(
|
||||
get_package_share_directory('rtabmap_demos'), 'config', 'demo_robot_mapping.rviz'
|
||||
)
|
||||
|
||||
# ---- image_proc rectification per camera ----
|
||||
def image_proc_nodes(side, color=False):
|
||||
ns = 'stereo_camera/' + side
|
||||
rectify = ComposableNode(
|
||||
package='image_proc', plugin='image_proc::RectifyNode',
|
||||
name='rectify_color_node' if color else 'rectify_mono_node', namespace=ns,
|
||||
remappings=[
|
||||
('image', 'image_color' if color else 'image_mono'),
|
||||
('camera_info', 'camera_info_throttle'),
|
||||
('image_rect', 'image_rect_color' if color else 'image_rect')],
|
||||
extra_arguments=intra_process)
|
||||
return [
|
||||
ComposableNode(
|
||||
package='image_proc', plugin='image_proc::DebayerNode',
|
||||
name='debayer_node', namespace=ns,
|
||||
extra_arguments=intra_process),
|
||||
rectify,
|
||||
]
|
||||
|
||||
# ---- rtabmap pipeline (always-on nodes) ----
|
||||
rtabmap_nodes = [
|
||||
# Synchronize stereo data together in a single topic
|
||||
# Issue: stereo_img_proc doesn't produce color and
|
||||
# grayscale images exactly the same (there is a small
|
||||
# vertical shift with color), we should use grayscale for
|
||||
# left and right images to get similar results than on ros1 noetic.
|
||||
ComposableNode(
|
||||
package='rtabmap_sync', plugin='rtabmap_sync::StereoSync',
|
||||
namespace='stereo_camera',
|
||||
remappings=[
|
||||
('left/image_rect', 'left/image_rect'),
|
||||
('right/image_rect', 'right/image_rect'),
|
||||
('left/camera_info', 'left/camera_info_throttle'),
|
||||
('right/camera_info', 'right/camera_info_throttle')],
|
||||
extra_arguments=intra_process),
|
||||
|
||||
# Visual odometry
|
||||
ComposableNode(
|
||||
package='rtabmap_odom', plugin='rtabmap_odom::StereoOdometry',
|
||||
parameters=[parameters],
|
||||
remappings=remappings,
|
||||
extra_arguments=intra_process),
|
||||
]
|
||||
|
||||
# Name of the shared component container.
|
||||
container_name = '/rtabmap_container'
|
||||
|
||||
return LaunchDescription([
|
||||
|
||||
# Launch arguments
|
||||
DeclareLaunchArgument('rtabmap_viz', default_value='false', description='Launch RTAB-Map UI (optional).'),
|
||||
DeclareLaunchArgument('rviz', default_value='true', description='Launch RVIZ (optional).'),
|
||||
DeclareLaunchArgument('localization', default_value='false', description='Launch in localization mode.'),
|
||||
DeclareLaunchArgument('rviz_cfg', default_value=config_rviz, description='Configuration path of rviz2.'),
|
||||
|
||||
SetParameter(name='use_sim_time', value=True),
|
||||
|
||||
# Nodes to launch
|
||||
|
||||
# Uncompress images for stereo_image_rect and remap to expected names from stereo_image_proc.
|
||||
Node(
|
||||
package='image_transport', executable='republish', name='republish_left', output='screen',
|
||||
namespace='stereo_camera',
|
||||
arguments=['compressed', 'raw'],
|
||||
remappings=[('in/compressed', 'left/image_raw_throttle/compressed'),
|
||||
('out', 'left/image_raw')]),
|
||||
Node(
|
||||
package='image_transport', executable='republish', name='republish_right', output='screen',
|
||||
namespace='stereo_camera',
|
||||
arguments=['compressed', 'raw'],
|
||||
remappings=[('in/compressed', 'right/image_raw_throttle/compressed'),
|
||||
('out', 'right/image_raw')]),
|
||||
|
||||
# Single component container holding the whole pipeline. All nodes set
|
||||
# use_intra_process_comms=True, so images are passed by pointer.
|
||||
ComposableNodeContainer(
|
||||
name='rtabmap_container',
|
||||
namespace='',
|
||||
package='rclcpp_components',
|
||||
executable='component_container',
|
||||
output='screen',
|
||||
composable_node_descriptions=
|
||||
image_proc_nodes('left') +
|
||||
image_proc_nodes('right') +
|
||||
rtabmap_nodes),
|
||||
|
||||
# SLAM mode (loaded into the shared container):
|
||||
# Note: latch=False. rtabmap latches its map/cloud/octomap/mapGraph
|
||||
# topics by default (transient_local QoS), which is incompatible with
|
||||
# intra-process comms ("intraprocess communication allowed only with
|
||||
# volatile durability"). Setting latch=False makes those topics volatile
|
||||
# so the node can join the zero-copy container. Trade-off: viewers that
|
||||
# start after a map is published won't get the retained last message,
|
||||
# but rtabmap republishes the map as it updates.
|
||||
LoadComposableNodes(
|
||||
condition=UnlessCondition(localization),
|
||||
target_container=container_name,
|
||||
composable_node_descriptions=[
|
||||
ComposableNode(
|
||||
package='rtabmap_slam', plugin='rtabmap_slam::CoreWrapper',
|
||||
parameters=[parameters,
|
||||
{'delete_db_on_start': True, # Equivalent of '-d': delete the previous database (~/.ros/rtabmap.db)
|
||||
'latch': False}],
|
||||
remappings=remappings,
|
||||
extra_arguments=intra_process),
|
||||
]),
|
||||
|
||||
# Localization mode (loaded into the shared container):
|
||||
LoadComposableNodes(
|
||||
condition=IfCondition(localization),
|
||||
target_container=container_name,
|
||||
composable_node_descriptions=[
|
||||
ComposableNode(
|
||||
package='rtabmap_slam', plugin='rtabmap_slam::CoreWrapper',
|
||||
parameters=[parameters,
|
||||
{'Mem/IncrementalMemory':'False',
|
||||
'Mem/InitWMWithAllNodes':'True',
|
||||
'latch': False}], # volatile QoS, see SLAM-mode note above
|
||||
remappings=remappings,
|
||||
extra_arguments=intra_process),
|
||||
]),
|
||||
|
||||
# Visualization:
|
||||
# Note: rtabmap_viz is launched as a standalone node, not as a component
|
||||
# in the container above. It is a Qt application and its UI must run in
|
||||
# the process main thread, while components are loaded in container
|
||||
# worker threads. So it cannot be composed and does not benefit from
|
||||
# intra-process comms here (the same applies to rviz2).
|
||||
Node(
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
condition=IfCondition(LaunchConfiguration("rtabmap_viz")),
|
||||
parameters=[parameters,
|
||||
{"odometry_node_name": 'stereo_odometry'}],
|
||||
remappings=remappings),
|
||||
Node(
|
||||
package='rviz2', executable='rviz2', name="rviz2", output='screen',
|
||||
condition=IfCondition(LaunchConfiguration("rviz")),
|
||||
arguments=[["-d"], [LaunchConfiguration("rviz_cfg")]]),
|
||||
])
|
||||
@@ -0,0 +1,91 @@
|
||||
# FusionCore + icp_odometry: TurtleBot3 Gazebo Demo
|
||||
|
||||
This demo shows a feedback loop between [FusionCore](https://github.com/manankharwar/fusioncore) and rtabmap's `icp_odometry` where each node tightens the other.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
/imu ──────────────────────┐
|
||||
/odom (wheel) ──────────────┤──→ FusionCore (UKF)
|
||||
/rtabmap/icp_odometry ──────┘ │
|
||||
↑ │ publishes: odom → base_footprint TF
|
||||
│ │ /fusion/odom
|
||||
│ guess_frame_id: odom│
|
||||
└────── icp_odometry ←───────┘
|
||||
│ (publish_tf: false)
|
||||
│
|
||||
└──→ /rtabmap/icp_odometry ──→ rtabmap SLAM ──→ map → odom TF
|
||||
```
|
||||
|
||||
**What each node contributes:**
|
||||
|
||||
| Node | Input | Provides |
|
||||
|---|---|---|
|
||||
| FusionCore | wheels + IMU | stable `odom` frame, continuous state at 100 Hz |
|
||||
| icp_odometry | `/scan` + FusionCore's `odom` as initial guess | scan-level pose corrections |
|
||||
| FusionCore encoder2 | icp_odometry output | tighter velocity corrections from ICP |
|
||||
| rtabmap SLAM | icp_odometry output | global map, loop closures |
|
||||
|
||||
FusionCore gives `icp_odometry` a stable initial guess via `guess_frame_id: odom`.
|
||||
Better initial guesses mean scan matching succeeds more often and with lower error.
|
||||
The ICP result feeds back into FusionCore as a second velocity source (`encoder2`),
|
||||
tightening the state estimate further. `Odom/ResetCountdown: 1` lets the system
|
||||
auto-recover if ICP loses tracking.
|
||||
|
||||
## Simulation vs real hardware
|
||||
|
||||
In Gazebo, the DiffDrive plugin produces near-perfect wheel velocities with no slip or
|
||||
encoder noise, while the simulated MPU9250 injects Gaussian noise. FusionCore fusing
|
||||
both means the noisy IMU slightly degrades what is already a perfect odometry source,
|
||||
so the `map → odom` correction on each scan update will be slightly larger than in the
|
||||
standard wheel-odometry-only demo. On real hardware this completely inverts: wheel
|
||||
encoders accumulate slip, terrain variation, and mechanical error that dwarfs IMU noise,
|
||||
and fusion pays off measurably. The sim-tuned IMU noise values in `fusioncore_tb3.yaml`
|
||||
(`gyro_noise: 0.002`, `accel_noise: 0.02`) reduce unnecessary filter uncertainty in
|
||||
simulation; real MPU9250 users should use the hardware spec values noted in that file.
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
export TURTLEBOT3_MODEL=waffle
|
||||
|
||||
ros2 launch rtabmap_demos turtlebot3_sim_fusioncore_icp_demo.launch.py
|
||||
```
|
||||
|
||||
Optional arguments:
|
||||
|
||||
```bash
|
||||
# Localization mode (requires saved map from a previous mapping run)
|
||||
ros2 launch rtabmap_demos turtlebot3_sim_fusioncore_icp_demo.launch.py localization:=true
|
||||
|
||||
# Different Gazebo world
|
||||
ros2 launch rtabmap_demos turtlebot3_sim_fusioncore_icp_demo.launch.py world:=house
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
```bash
|
||||
sudo apt install ros-jazzy-fusioncore-ros ros-jazzy-turtlebot3-gazebo ros-jazzy-rtabmap-ros ros-jazzy-nav2-bringup
|
||||
export TURTLEBOT3_MODEL=waffle
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `turtlebot3_sim_fusioncore_icp_demo.launch.py` | Complete demo: Gazebo + FusionCore + rtabmap + Nav2 |
|
||||
| `turtlebot3_fusioncore_icp.launch.py` | Core only: FusionCore + icp_odometry + rtabmap (no Gazebo) |
|
||||
| `../../params/fusioncore_tb3.yaml` | FusionCore config for TB3 Waffle |
|
||||
| `../../params/turtlebot3_fusioncore_icp_nav2_params.yaml` | Nav2 config using `/fusion/odom` |
|
||||
|
||||
## Topic and TF summary
|
||||
|
||||
| Topic / TF | Publisher | Subscribers |
|
||||
|---|---|---|
|
||||
| `/imu` | Gazebo | FusionCore |
|
||||
| `/odom` | Gazebo (wheel) | FusionCore |
|
||||
| `/scan` | Gazebo (lidar) | icp_odometry, rtabmap |
|
||||
| `/rtabmap/icp_odometry` | icp_odometry | FusionCore (encoder2), rtabmap |
|
||||
| `/fusion/odom` | FusionCore | Nav2 |
|
||||
| TF `odom → base_footprint` | FusionCore | icp_odometry (guess), Nav2 |
|
||||
| TF `map → odom` | rtabmap | Nav2 |
|
||||
@@ -0,0 +1,165 @@
|
||||
"""
|
||||
FusionCore + icp_odometry feedback loop for TurtleBot3.
|
||||
|
||||
Architecture (Option A from rtabmap_ros issue #1418):
|
||||
|
||||
FusionCore (wheels + IMU)
|
||||
|-- publishes: odom -> base_footprint TF, /fusion/odom
|
||||
|-- provides initial pose guess to icp_odometry via guess_frame_id
|
||||
|
||||
icp_odometry (/scan)
|
||||
|-- guess_frame_id: odom (uses FusionCore's stable odom as scan match seed)
|
||||
|-- publish_tf: false (FusionCore owns the odom TF)
|
||||
|-- publishes: /rtabmap/icp_odometry
|
||||
|
||||
FusionCore encoder2
|
||||
|-- topic: /rtabmap/icp_odometry
|
||||
|-- ICP corrections fed back as a second velocity source
|
||||
|
||||
rtabmap SLAM
|
||||
|-- subscribes to /rtabmap/icp_odometry for mapping
|
||||
|-- Odom/ResetCountdown: 1 for auto-recovery if ICP loses tracking
|
||||
|-- publishes: map -> odom TF
|
||||
"""
|
||||
|
||||
import os
|
||||
from ament_index_python.packages import get_package_share_directory
|
||||
from launch import LaunchDescription
|
||||
from launch.actions import (DeclareLaunchArgument, EmitEvent,
|
||||
OpaqueFunction, RegisterEventHandler, TimerAction)
|
||||
from launch.substitutions import LaunchConfiguration
|
||||
from launch_ros.actions import LifecycleNode, Node
|
||||
from launch_ros.event_handlers import OnStateTransition
|
||||
from launch_ros.events.lifecycle import ChangeState
|
||||
from lifecycle_msgs.msg import Transition
|
||||
|
||||
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
use_sim_time = LaunchConfiguration('use_sim_time')
|
||||
localization = LaunchConfiguration('localization').perform(context)
|
||||
localization = localization in ('True', 'true')
|
||||
|
||||
pkg_demos = get_package_share_directory('rtabmap_demos')
|
||||
fusioncore_config = os.path.join(pkg_demos, 'params', 'fusioncore_tb3.yaml')
|
||||
|
||||
# ── FusionCore lifecycle node ─────────────────────────────────────────────
|
||||
fc = LifecycleNode(
|
||||
package='fusioncore_ros',
|
||||
executable='fusioncore_node',
|
||||
name='fusioncore',
|
||||
namespace='',
|
||||
output='screen',
|
||||
parameters=[fusioncore_config, {'use_sim_time': use_sim_time}],
|
||||
remappings=[
|
||||
('/imu/data', '/imu'), # TB3 Gazebo IMU topic
|
||||
('/odom/wheels', '/odom'), # TB3 Gazebo wheel odometry topic
|
||||
],
|
||||
)
|
||||
|
||||
# Wait 2 s for node to spin up, then configure
|
||||
configure = TimerAction(
|
||||
period=2.0,
|
||||
actions=[EmitEvent(event=ChangeState(
|
||||
lifecycle_node_matcher=lambda a: a is fc,
|
||||
transition_id=Transition.TRANSITION_CONFIGURE,
|
||||
))],
|
||||
)
|
||||
|
||||
# As soon as configuring -> inactive, activate
|
||||
activate = RegisterEventHandler(OnStateTransition(
|
||||
target_lifecycle_node=fc,
|
||||
start_state='configuring',
|
||||
goal_state='inactive',
|
||||
entities=[EmitEvent(event=ChangeState(
|
||||
lifecycle_node_matcher=lambda a: a is fc,
|
||||
transition_id=Transition.TRANSITION_ACTIVATE,
|
||||
))],
|
||||
))
|
||||
|
||||
# ── icp_odometry ──────────────────────────────────────────────────────────
|
||||
icp_parameters = {
|
||||
'frame_id': 'base_footprint',
|
||||
'odom_frame_id': 'odom',
|
||||
'guess_frame_id': 'odom',
|
||||
'publish_tf': False,
|
||||
'publish_null_when_lost': False,
|
||||
'use_sim_time': use_sim_time,
|
||||
'Reg/Strategy': '1',
|
||||
'Reg/Force3DoF': 'true',
|
||||
'Odom/ResetCountdown': '1',
|
||||
'RGBD/NeighborLinkRefining': 'True',
|
||||
'Grid/RangeMin': '0.2',
|
||||
}
|
||||
|
||||
icp_odometry_node = Node(
|
||||
package='rtabmap_odom',
|
||||
executable='icp_odometry',
|
||||
output='screen',
|
||||
parameters=[icp_parameters],
|
||||
remappings=[
|
||||
('scan', '/scan'),
|
||||
('odom', '/rtabmap/icp_odometry'),
|
||||
],
|
||||
)
|
||||
|
||||
# ── rtabmap SLAM ──────────────────────────────────────────────────────────
|
||||
slam_parameters = {
|
||||
'frame_id': 'base_footprint',
|
||||
'odom_frame_id': 'odom',
|
||||
'use_sim_time': use_sim_time,
|
||||
'subscribe_depth': False,
|
||||
'subscribe_rgb': False,
|
||||
'subscribe_scan': True,
|
||||
'approx_sync': True,
|
||||
'use_action_for_goal': True,
|
||||
'Reg/Strategy': '1',
|
||||
'Reg/Force3DoF': 'true',
|
||||
'RGBD/NeighborLinkRefining': 'True',
|
||||
'Grid/RangeMin': '0.2',
|
||||
'Optimizer/GravitySigma': '0',
|
||||
}
|
||||
|
||||
if localization:
|
||||
slam_parameters['Mem/IncrementalMemory'] = 'False'
|
||||
slam_parameters['Mem/InitWMWithAllNodes'] = 'True'
|
||||
|
||||
rtabmap_args = [] if localization else ['-d']
|
||||
|
||||
rtabmap_node = Node(
|
||||
package='rtabmap_slam',
|
||||
executable='rtabmap',
|
||||
output='screen',
|
||||
parameters=[slam_parameters],
|
||||
remappings=[
|
||||
('scan', '/scan'),
|
||||
('odom', '/rtabmap/icp_odometry'),
|
||||
],
|
||||
arguments=rtabmap_args,
|
||||
)
|
||||
|
||||
rtabmap_viz_node = Node(
|
||||
package='rtabmap_viz',
|
||||
executable='rtabmap_viz',
|
||||
output='screen',
|
||||
parameters=[slam_parameters, {'odometry_node_name': 'icp_odometry'}],
|
||||
remappings=[
|
||||
('scan', '/scan'),
|
||||
('odom', '/rtabmap/icp_odometry'),
|
||||
],
|
||||
)
|
||||
|
||||
return [fc, configure, activate, icp_odometry_node, rtabmap_node, rtabmap_viz_node]
|
||||
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
DeclareLaunchArgument(
|
||||
'use_sim_time', default_value='true',
|
||||
description='Use simulation (Gazebo) clock if true'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'localization', default_value='false',
|
||||
description='Launch in localization mode (requires existing map)'),
|
||||
|
||||
OpaqueFunction(function=launch_setup),
|
||||
])
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
"""
|
||||
Complete TurtleBot3 demo: Gazebo (new) + FusionCore + icp_odometry + Nav2.
|
||||
|
||||
Launches in order:
|
||||
1. Gazebo Harmonic (via ros_gz_sim) with turtlebot3_world
|
||||
2. Robot state publisher + spawn TurtleBot3
|
||||
3. Custom ros_gz_bridge WITHOUT the odom TF (FusionCore owns odom->base_footprint)
|
||||
4. FusionCore lifecycle node (configure -> activate automatically)
|
||||
5. icp_odometry using FusionCore's odom frame as scan-match initial guess
|
||||
6. rtabmap SLAM subscribing to icp_odometry output
|
||||
7. Nav2 using /fusion/odom
|
||||
|
||||
Usage:
|
||||
export TURTLEBOT3_MODEL=waffle
|
||||
ros2 launch rtabmap_demos turtlebot3_sim_fusioncore_icp_demo.launch.py
|
||||
|
||||
# Localization mode (requires existing map):
|
||||
ros2 launch rtabmap_demos turtlebot3_sim_fusioncore_icp_demo.launch.py localization:=true
|
||||
|
||||
# Different world:
|
||||
ros2 launch rtabmap_demos turtlebot3_sim_fusioncore_icp_demo.launch.py world:=house
|
||||
|
||||
Note on TF ownership:
|
||||
The standard turtlebot3_gazebo bridge forwards the DiffDrive TF to ROS, which
|
||||
conflicts with FusionCore's odom->base_footprint. This demo uses a custom bridge
|
||||
config (fusioncore_tb3_bridge.yaml) that suppresses the Gazebo TF entry.
|
||||
FusionCore is the sole publisher of odom->base_footprint.
|
||||
"""
|
||||
|
||||
import os
|
||||
from ament_index_python.packages import get_package_share_directory
|
||||
from launch import LaunchDescription
|
||||
from launch.actions import (AppendEnvironmentVariable, DeclareLaunchArgument,
|
||||
IncludeLaunchDescription, OpaqueFunction)
|
||||
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||||
from launch_ros.actions import Node
|
||||
from launch_ros.substitutions import FindPackageShare
|
||||
|
||||
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
if 'TURTLEBOT3_MODEL' not in os.environ:
|
||||
os.environ['TURTLEBOT3_MODEL'] = 'waffle'
|
||||
|
||||
tb3_model = os.environ['TURTLEBOT3_MODEL']
|
||||
pkg_tb3_gz = get_package_share_directory('turtlebot3_gazebo')
|
||||
pkg_ros_gz = get_package_share_directory('ros_gz_sim')
|
||||
pkg_nav2 = get_package_share_directory('nav2_bringup')
|
||||
pkg_demos = get_package_share_directory('rtabmap_demos')
|
||||
|
||||
world_name = LaunchConfiguration('world').perform(context)
|
||||
world_file = os.path.join(pkg_tb3_gz, 'worlds', f'turtlebot3_{world_name}.world')
|
||||
|
||||
# ── Gazebo server + client ────────────────────────────────────────────────
|
||||
gz_server = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_ros_gz, 'launch', 'gz_sim.launch.py')),
|
||||
launch_arguments={
|
||||
'gz_args': f'-r -s -v2 {world_file}',
|
||||
'on_exit_shutdown': 'true',
|
||||
}.items(),
|
||||
)
|
||||
gz_client = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_ros_gz, 'launch', 'gz_sim.launch.py')),
|
||||
launch_arguments={'gz_args': '-g -v2', 'on_exit_shutdown': 'true'}.items(),
|
||||
)
|
||||
|
||||
# ── Robot state publisher ─────────────────────────────────────────────────
|
||||
robot_state_publisher = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_tb3_gz, 'launch', 'robot_state_publisher.launch.py')),
|
||||
launch_arguments={'use_sim_time': 'true'}.items(),
|
||||
)
|
||||
|
||||
# ── Spawn TurtleBot3 (entity only, no bridge) ─────────────────────────────
|
||||
urdf_path = os.path.join(pkg_tb3_gz, 'models',
|
||||
f'turtlebot3_{tb3_model}', 'model.sdf')
|
||||
spawn_robot = Node(
|
||||
package='ros_gz_sim',
|
||||
executable='create',
|
||||
arguments=[
|
||||
'-name', tb3_model,
|
||||
'-file', urdf_path,
|
||||
'-x', LaunchConfiguration('x_pose'),
|
||||
'-y', LaunchConfiguration('y_pose'),
|
||||
'-z', '0.01',
|
||||
],
|
||||
output='screen',
|
||||
)
|
||||
|
||||
# ── Custom bridge: all topics EXCEPT odom TF ──────────────────────────────
|
||||
# FusionCore publishes odom->base_footprint; suppress the Gazebo DiffDrive TF.
|
||||
bridge_config = os.path.join(pkg_demos, 'params', 'fusioncore_tb3_bridge.yaml')
|
||||
bridge = Node(
|
||||
package='ros_gz_bridge',
|
||||
executable='parameter_bridge',
|
||||
arguments=['--ros-args', '-p', f'config_file:={bridge_config}'],
|
||||
output='screen',
|
||||
)
|
||||
|
||||
# Camera image bridge (waffle only)
|
||||
image_bridge = Node(
|
||||
package='ros_gz_image',
|
||||
executable='image_bridge',
|
||||
arguments=['/camera/image_raw'],
|
||||
output='screen',
|
||||
)
|
||||
|
||||
# ── FusionCore + icp_odometry + rtabmap ───────────────────────────────────
|
||||
fusioncore_icp = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_demos, 'launch', 'turtlebot3', 'fusioncore',
|
||||
'turtlebot3_fusioncore_icp.launch.py')),
|
||||
launch_arguments=[
|
||||
('localization', LaunchConfiguration('localization')),
|
||||
('use_sim_time', 'true'),
|
||||
],
|
||||
)
|
||||
|
||||
# ── Nav2 ──────────────────────────────────────────────────────────────────
|
||||
nav2 = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_nav2, 'launch', 'navigation_launch.py')),
|
||||
launch_arguments=[
|
||||
('use_sim_time', 'true'),
|
||||
('params_file', PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params',
|
||||
'turtlebot3_fusioncore_icp_nav2_params.yaml'])),
|
||||
],
|
||||
)
|
||||
|
||||
rviz = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_nav2, 'launch', 'rviz_launch.py')),
|
||||
)
|
||||
|
||||
set_gz_resource_path = AppendEnvironmentVariable(
|
||||
'GZ_SIM_RESOURCE_PATH',
|
||||
os.path.join(pkg_tb3_gz, 'models'),
|
||||
)
|
||||
|
||||
nodes = [
|
||||
set_gz_resource_path,
|
||||
gz_server,
|
||||
gz_client,
|
||||
robot_state_publisher,
|
||||
spawn_robot,
|
||||
bridge,
|
||||
fusioncore_icp,
|
||||
nav2,
|
||||
rviz,
|
||||
]
|
||||
if tb3_model == 'waffle':
|
||||
nodes.insert(6, image_bridge)
|
||||
|
||||
return nodes
|
||||
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
DeclareLaunchArgument(
|
||||
'localization', default_value='false',
|
||||
description='Launch in localization mode.'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'world', default_value='world',
|
||||
choices=['world', 'house', 'dqn_stage1', 'dqn_stage2',
|
||||
'dqn_stage3', 'dqn_stage4'],
|
||||
description='Turtlebot3 Gazebo world.'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'x_pose', default_value='-2.0',
|
||||
description='Initial X position in Gazebo.'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'y_pose', default_value='-0.5',
|
||||
description='Initial Y position in Gazebo.'),
|
||||
|
||||
OpaqueFunction(function=launch_setup),
|
||||
])
|
||||
@@ -20,11 +20,13 @@ from launch.actions import DeclareLaunchArgument, SetEnvironmentVariable
|
||||
from launch.substitutions import LaunchConfiguration
|
||||
from launch.conditions import IfCondition, UnlessCondition
|
||||
from launch_ros.actions import Node
|
||||
from launch.actions import OpaqueFunction
|
||||
|
||||
def generate_launch_description():
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
|
||||
use_sim_time = LaunchConfiguration('use_sim_time')
|
||||
localization = LaunchConfiguration('localization')
|
||||
max_ground_height = LaunchConfiguration('max_ground_height').perform(context)
|
||||
|
||||
parameters={
|
||||
'frame_id':'base_footprint',
|
||||
@@ -36,7 +38,7 @@ def generate_launch_description():
|
||||
'Grid/3D':'false', # Use 2D occupancy
|
||||
'Grid/RangeMax':'3',
|
||||
'Grid/NormalsSegmentation':'false', # Use passthrough filter to detect obstacles
|
||||
'Grid/MaxGroundHeight':'0.05', # All points above 5 cm are obstacles
|
||||
'Grid/MaxGroundHeight': str(max_ground_height), # All points above 5 cm are obstacles
|
||||
'Grid/MaxObstacleHeight':'0.4', # All points over 1 meter are ignored
|
||||
'Optimizer/GravitySigma':'0' # Disable imu constraints (we are already in 2D)
|
||||
}
|
||||
@@ -46,17 +48,7 @@ def generate_launch_description():
|
||||
('rgb/camera_info', '/camera/camera_info'),
|
||||
('depth/image', '/camera/depth/image_raw')]
|
||||
|
||||
return LaunchDescription([
|
||||
|
||||
# Launch arguments
|
||||
DeclareLaunchArgument(
|
||||
'use_sim_time', default_value='true',
|
||||
description='Use simulation (Gazebo) clock if true'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'localization', default_value='false',
|
||||
description='Launch in localization mode.'),
|
||||
|
||||
return [
|
||||
# Nodes to launch
|
||||
|
||||
# SLAM mode:
|
||||
@@ -98,4 +90,23 @@ def generate_launch_description():
|
||||
remappings=[('cloud', '/camera/cloud'),
|
||||
('obstacles', '/camera/obstacles'),
|
||||
('ground', '/camera/ground')]),
|
||||
])
|
||||
]
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
|
||||
# Launch arguments
|
||||
DeclareLaunchArgument(
|
||||
'use_sim_time', default_value='true',
|
||||
description='Use simulation (Gazebo) clock if true'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'localization', default_value='false',
|
||||
description='Launch in localization mode.'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'max_ground_height', default_value='0.05',
|
||||
description='Maximum ground height, everything above is obstacle'),
|
||||
|
||||
OpaqueFunction(function=launch_setup)
|
||||
])
|
||||
@@ -20,12 +20,13 @@ from launch.actions import DeclareLaunchArgument, SetEnvironmentVariable
|
||||
from launch.substitutions import LaunchConfiguration
|
||||
from launch.conditions import IfCondition, UnlessCondition
|
||||
from launch_ros.actions import Node
|
||||
from launch.actions import OpaqueFunction
|
||||
|
||||
|
||||
def generate_launch_description():
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
|
||||
use_sim_time = LaunchConfiguration('use_sim_time')
|
||||
localization = LaunchConfiguration('localization')
|
||||
max_ground_height = LaunchConfiguration('max_ground_height').perform(context)
|
||||
|
||||
parameters={
|
||||
'frame_id':'base_footprint',
|
||||
@@ -42,7 +43,7 @@ def generate_launch_description():
|
||||
'Grid/RangeMax':'3',
|
||||
'Grid/NormalsSegmentation':'false', # Use passthrough filter to detect obstacles
|
||||
'Grid/Sensor':'2', # Use both laser scan and camera for obstacle detection in global map
|
||||
'Grid/MaxGroundHeight':'0.05', # All points above 5 cm are obstacles
|
||||
'Grid/MaxGroundHeight': str(max_ground_height), # All points above are obstacles
|
||||
'Grid/MaxObstacleHeight':'0.4', # All points over 1 meter are ignored
|
||||
'Grid/RangeMin':'0.2', # ignore laser scan points on the robot itself
|
||||
'Optimizer/GravitySigma':'0' # Disable imu constraints (we are already in 2D)
|
||||
@@ -53,17 +54,7 @@ def generate_launch_description():
|
||||
('rgb/camera_info', '/camera/camera_info'),
|
||||
('depth/image', '/camera/depth/image_raw')]
|
||||
|
||||
return LaunchDescription([
|
||||
|
||||
# Launch arguments
|
||||
DeclareLaunchArgument(
|
||||
'use_sim_time', default_value='false',
|
||||
description='Use simulation (Gazebo) clock if true'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'localization', default_value='false',
|
||||
description='Launch in localization mode.'),
|
||||
|
||||
return [
|
||||
# Nodes to launch
|
||||
Node(
|
||||
package='rtabmap_sync', executable='rgbd_sync', output='screen',
|
||||
@@ -109,4 +100,23 @@ def generate_launch_description():
|
||||
remappings=[('cloud', '/camera/cloud'),
|
||||
('obstacles', '/camera/obstacles'),
|
||||
('ground', '/camera/ground')]),
|
||||
])
|
||||
]
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
|
||||
# Launch arguments
|
||||
DeclareLaunchArgument(
|
||||
'use_sim_time', default_value='true',
|
||||
description='Use simulation (Gazebo) clock if true'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'localization', default_value='false',
|
||||
description='Launch in localization mode.'),
|
||||
|
||||
DeclareLaunchArgument(
|
||||
'max_ground_height', default_value='0.05',
|
||||
description='Maximum ground height, everything above is obstacle'),
|
||||
|
||||
OpaqueFunction(function=launch_setup)
|
||||
])
|
||||
@@ -76,7 +76,8 @@ def launch_setup(context, *args, **kwargs):
|
||||
# Visualization
|
||||
Node(
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
parameters=[parameters],
|
||||
parameters=[parameters,
|
||||
{"odometry_node_name": 'icp_odometry'}],
|
||||
remappings=remappings),
|
||||
]
|
||||
|
||||
|
||||
@@ -13,8 +13,30 @@
|
||||
# </joint>
|
||||
# 3) Rename <link name="camera_rgb_frame"> to <link name="camera_rgb_optical_frame">
|
||||
# 4) Add <link name="camera_rgb_frame"/>
|
||||
# 5) Change <sensor name="camera" type="camera"> to <sensor name="camera" type="depth">
|
||||
# 6) Change image width/height from 1920x1080 to 640x480
|
||||
# 5) Change image width/height from 1920x1080 to 640x480
|
||||
# 6) [ROS2 HUMBLE] Change <sensor name="camera" type="camera"> to <sensor name="camera" type="depth">
|
||||
# 6) [ROS2 JAZZY] Change <gz_frame_id>camera_rgb_frame</gz_frame_id> to <gz_frame_id>camera_rgb_optical_frame</gz_frame_id>
|
||||
# 7) [ROS2 JAZZY] Add the following just after <sensor name="camera" ...> section
|
||||
# <sensor name="depth" type="depth">
|
||||
# <always_on>true</always_on>
|
||||
# <visualize>true</visualize>
|
||||
# <update_rate>30</update_rate>
|
||||
# <topic>camera/depth/image_raw</topic>
|
||||
# <gz_frame_id>camera_rgb_optical_frame</gz_frame_id>
|
||||
# <camera name="intel_realsense_r200_depth">
|
||||
# <camera_info_topic>camera/depth/camera_info</camera_info_topic>
|
||||
# <horizontal_fov>1.02974</horizontal_fov>
|
||||
# <image>
|
||||
# <width>640</width>
|
||||
# <height>480</height>
|
||||
# <format>R8G8B8</format>
|
||||
# </image>
|
||||
# <clip>
|
||||
# <near>0.02</near>
|
||||
# <far>300</far>
|
||||
# </clip>
|
||||
# </camera>
|
||||
# </sensor>
|
||||
# Example:
|
||||
# $ ros2 launch rtabmap_demos turtlebot3_sim_rgbd_demo.launch.py
|
||||
#
|
||||
@@ -28,9 +50,12 @@ from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, Opaq
|
||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||||
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||
from launch_ros.substitutions import FindPackageShare
|
||||
from launch_ros.actions import Node
|
||||
|
||||
import os
|
||||
|
||||
ROS_DISTRO = os.environ.get('ROS_DISTRO')
|
||||
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
if not 'TURTLEBOT3_MODEL' in os.environ:
|
||||
os.environ['TURTLEBOT3_MODEL'] = 'waffle'
|
||||
@@ -45,9 +70,14 @@ def launch_setup(context, *args, **kwargs):
|
||||
|
||||
world = LaunchConfiguration('world').perform(context)
|
||||
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_rgbd_nav2_params.yaml']
|
||||
)
|
||||
if ROS_DISTRO == 'humble':
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'humble', 'turtlebot3_rgbd_nav2_params.yaml']
|
||||
)
|
||||
else:
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_rgbd_nav2_params.yaml']
|
||||
)
|
||||
|
||||
# Paths
|
||||
gazebo_launch = PathJoinSubstitution(
|
||||
@@ -60,13 +90,22 @@ def launch_setup(context, *args, **kwargs):
|
||||
[pkg_rtabmap_demos, 'launch', 'turtlebot3', 'turtlebot3_rgbd.launch.py'])
|
||||
|
||||
# Includes
|
||||
gazebo = IncludeLaunchDescription(
|
||||
gazebo = [IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([gazebo_launch]),
|
||||
launch_arguments=[
|
||||
('x_pose', LaunchConfiguration('x_pose')),
|
||||
('y_pose', LaunchConfiguration('y_pose'))
|
||||
]
|
||||
)
|
||||
)]
|
||||
if ROS_DISTRO != 'humble':
|
||||
start_gazebo_ros_depth_image_bridge_cmd = Node(
|
||||
package='ros_gz_image',
|
||||
executable='image_bridge',
|
||||
arguments=['/camera/depth/image_raw'],
|
||||
output='screen',
|
||||
)
|
||||
gazebo.append(start_gazebo_ros_depth_image_bridge_cmd)
|
||||
|
||||
nav2 = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([nav2_launch]),
|
||||
launch_arguments=[
|
||||
@@ -77,20 +116,25 @@ def launch_setup(context, *args, **kwargs):
|
||||
rviz = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([rviz_launch])
|
||||
)
|
||||
|
||||
max_ground_height = '0.05'
|
||||
if ROS_DISTRO == 'jazzy':
|
||||
max_ground_height = '0.02' # for the demo, on new gazebo the depth is more accurate
|
||||
|
||||
rtabmap = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([rtabmap_launch]),
|
||||
launch_arguments=[
|
||||
('localization', LaunchConfiguration('localization')),
|
||||
('use_sim_time', 'true')
|
||||
('use_sim_time', 'true'),
|
||||
('max_ground_height', max_ground_height)
|
||||
]
|
||||
)
|
||||
return [
|
||||
# Nodes to launch
|
||||
nav2,
|
||||
rviz,
|
||||
rtabmap,
|
||||
gazebo
|
||||
]
|
||||
rtabmap
|
||||
] + gazebo
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
|
||||
@@ -13,8 +13,30 @@
|
||||
# </joint>
|
||||
# 3) Rename <link name="camera_rgb_frame"> to <link name="camera_rgb_optical_frame">
|
||||
# 4) Add <link name="camera_rgb_frame"/>
|
||||
# 5) Change <sensor name="camera" type="camera"> to <sensor name="camera" type="depth">
|
||||
# 6) Change image width/height from 1920x1080 to 640x480
|
||||
# 5) Change image width/height from 1920x1080 to 640x480
|
||||
# 6) [ROS2 HUMBLE] Change <sensor name="camera" type="camera"> to <sensor name="camera" type="depth">
|
||||
# 6) [ROS2 JAZZY] Change <gz_frame_id>camera_rgb_frame</gz_frame_id> to <gz_frame_id>camera_rgb_optical_frame</gz_frame_id>
|
||||
# 7) [ROS2 JAZZY] Add the following just after <sensor name="camera" ...> section (under same link)
|
||||
# <sensor name="depth" type="depth">
|
||||
# <always_on>true</always_on>
|
||||
# <visualize>true</visualize>
|
||||
# <update_rate>30</update_rate>
|
||||
# <topic>camera/depth/image_raw</topic>
|
||||
# <gz_frame_id>camera_rgb_optical_frame</gz_frame_id>
|
||||
# <camera name="intel_realsense_r200_depth">
|
||||
# <camera_info_topic>camera/depth/camera_info</camera_info_topic>
|
||||
# <horizontal_fov>1.02974</horizontal_fov>
|
||||
# <image>
|
||||
# <width>640</width>
|
||||
# <height>480</height>
|
||||
# <format>R8G8B8</format>
|
||||
# </image>
|
||||
# <clip>
|
||||
# <near>0.02</near>
|
||||
# <far>300</far>
|
||||
# </clip>
|
||||
# </camera>
|
||||
# </sensor>
|
||||
# Example:
|
||||
# $ ros2 launch rtabmap_demos turtlebot3_sim_rgbd_fake_scan_demo.launch.py
|
||||
#
|
||||
@@ -28,9 +50,12 @@ from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, Opaq
|
||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||||
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||
from launch_ros.substitutions import FindPackageShare
|
||||
from launch_ros.actions import Node
|
||||
|
||||
import os
|
||||
|
||||
ROS_DISTRO = os.environ.get('ROS_DISTRO')
|
||||
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
if not 'TURTLEBOT3_MODEL' in os.environ:
|
||||
os.environ['TURTLEBOT3_MODEL'] = 'waffle'
|
||||
@@ -45,9 +70,14 @@ def launch_setup(context, *args, **kwargs):
|
||||
|
||||
world = LaunchConfiguration('world').perform(context)
|
||||
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_rgbd_nav2_params.yaml']
|
||||
)
|
||||
if ROS_DISTRO == 'humble':
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'humble', 'turtlebot3_rgbd_nav2_params.yaml']
|
||||
)
|
||||
else:
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_rgbd_nav2_params.yaml']
|
||||
)
|
||||
|
||||
# Paths
|
||||
gazebo_launch = PathJoinSubstitution(
|
||||
@@ -60,13 +90,22 @@ def launch_setup(context, *args, **kwargs):
|
||||
[pkg_rtabmap_demos, 'launch', 'turtlebot3', 'turtlebot3_rgbd_fake_scan.launch.py'])
|
||||
|
||||
# Includes
|
||||
gazebo = IncludeLaunchDescription(
|
||||
gazebo = [IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([gazebo_launch]),
|
||||
launch_arguments=[
|
||||
('x_pose', LaunchConfiguration('x_pose')),
|
||||
('y_pose', LaunchConfiguration('y_pose'))
|
||||
]
|
||||
)
|
||||
)]
|
||||
if ROS_DISTRO != 'humble':
|
||||
start_gazebo_ros_depth_image_bridge_cmd = Node(
|
||||
package='ros_gz_image',
|
||||
executable='image_bridge',
|
||||
arguments=['/camera/depth/image_raw'],
|
||||
output='screen',
|
||||
)
|
||||
gazebo.append(start_gazebo_ros_depth_image_bridge_cmd)
|
||||
|
||||
nav2 = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([nav2_launch]),
|
||||
launch_arguments=[
|
||||
@@ -77,6 +116,7 @@ def launch_setup(context, *args, **kwargs):
|
||||
rviz = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([rviz_launch])
|
||||
)
|
||||
|
||||
rtabmap = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([rtabmap_launch]),
|
||||
launch_arguments=[
|
||||
@@ -88,9 +128,8 @@ def launch_setup(context, *args, **kwargs):
|
||||
# Nodes to launch
|
||||
nav2,
|
||||
rviz,
|
||||
rtabmap,
|
||||
gazebo
|
||||
]
|
||||
rtabmap
|
||||
] + gazebo
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
|
||||
@@ -13,8 +13,30 @@
|
||||
# </joint>
|
||||
# 3) Rename <link name="camera_rgb_frame"> to <link name="camera_rgb_optical_frame">
|
||||
# 4) Add <link name="camera_rgb_frame"/>
|
||||
# 5) Change <sensor name="camera" type="camera"> to <sensor name="camera" type="depth">
|
||||
# 6) Change image width/height from 1920x1080 to 640x480
|
||||
# 5) Change image width/height from 1920x1080 to 640x480
|
||||
# 6) [ROS2 HUMBLE] Change <sensor name="camera" type="camera"> to <sensor name="camera" type="depth">
|
||||
# 6) [ROS2 JAZZY] Change <gz_frame_id>camera_rgb_frame</gz_frame_id> to <gz_frame_id>camera_rgb_optical_frame</gz_frame_id>
|
||||
# 7) [ROS2 JAZZY] Add the following just after <sensor name="camera" ...> section (under same link)
|
||||
# <sensor name="depth" type="depth">
|
||||
# <always_on>true</always_on>
|
||||
# <visualize>true</visualize>
|
||||
# <update_rate>30</update_rate>
|
||||
# <topic>camera/depth/image_raw</topic>
|
||||
# <gz_frame_id>camera_rgb_optical_frame</gz_frame_id>
|
||||
# <camera name="intel_realsense_r200_depth">
|
||||
# <camera_info_topic>camera/depth/camera_info</camera_info_topic>
|
||||
# <horizontal_fov>1.02974</horizontal_fov>
|
||||
# <image>
|
||||
# <width>640</width>
|
||||
# <height>480</height>
|
||||
# <format>R8G8B8</format>
|
||||
# </image>
|
||||
# <clip>
|
||||
# <near>0.02</near>
|
||||
# <far>300</far>
|
||||
# </clip>
|
||||
# </camera>
|
||||
# </sensor>
|
||||
# 7) Note that we can increase min scan range from 0.12 to 0.2 to avoid having scans
|
||||
# hitting the robot itself
|
||||
# Example:
|
||||
@@ -30,9 +52,12 @@ from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, Opaq
|
||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||||
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||
from launch_ros.substitutions import FindPackageShare
|
||||
from launch_ros.actions import Node
|
||||
|
||||
import os
|
||||
|
||||
ROS_DISTRO = os.environ.get('ROS_DISTRO')
|
||||
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
if not 'TURTLEBOT3_MODEL' in os.environ:
|
||||
os.environ['TURTLEBOT3_MODEL'] = 'waffle'
|
||||
@@ -47,9 +72,14 @@ def launch_setup(context, *args, **kwargs):
|
||||
|
||||
world = LaunchConfiguration('world').perform(context)
|
||||
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_rgbd_scan_nav2_params.yaml']
|
||||
)
|
||||
if ROS_DISTRO == 'humble':
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'humble', 'turtlebot3_rgbd_scan_nav2_params.yaml']
|
||||
)
|
||||
else:
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_rgbd_scan_nav2_params.yaml']
|
||||
)
|
||||
|
||||
# Paths
|
||||
gazebo_launch = PathJoinSubstitution(
|
||||
@@ -62,13 +92,22 @@ def launch_setup(context, *args, **kwargs):
|
||||
[pkg_rtabmap_demos, 'launch', 'turtlebot3', 'turtlebot3_rgbd_scan.launch.py'])
|
||||
|
||||
# Includes
|
||||
gazebo = IncludeLaunchDescription(
|
||||
gazebo = [IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([gazebo_launch]),
|
||||
launch_arguments=[
|
||||
('x_pose', LaunchConfiguration('x_pose')),
|
||||
('y_pose', LaunchConfiguration('y_pose'))
|
||||
]
|
||||
)
|
||||
)]
|
||||
if ROS_DISTRO != 'humble':
|
||||
start_gazebo_ros_depth_image_bridge_cmd = Node(
|
||||
package='ros_gz_image',
|
||||
executable='image_bridge',
|
||||
arguments=['/camera/depth/image_raw'],
|
||||
output='screen',
|
||||
)
|
||||
gazebo.append(start_gazebo_ros_depth_image_bridge_cmd)
|
||||
|
||||
nav2 = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([nav2_launch]),
|
||||
launch_arguments=[
|
||||
@@ -79,20 +118,25 @@ def launch_setup(context, *args, **kwargs):
|
||||
rviz = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([rviz_launch])
|
||||
)
|
||||
|
||||
max_ground_height = '0.05'
|
||||
if ROS_DISTRO == 'jazzy':
|
||||
max_ground_height = '0.02' # for the demo, on new gazebo the depth is more accurate
|
||||
|
||||
rtabmap = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([rtabmap_launch]),
|
||||
launch_arguments=[
|
||||
('localization', LaunchConfiguration('localization')),
|
||||
('use_sim_time', 'true')
|
||||
('use_sim_time', 'true'),
|
||||
('max_ground_height', max_ground_height)
|
||||
]
|
||||
)
|
||||
return [
|
||||
# Nodes to launch
|
||||
nav2,
|
||||
rviz,
|
||||
rtabmap,
|
||||
gazebo
|
||||
]
|
||||
rtabmap
|
||||
] + gazebo
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
|
||||
@@ -14,18 +14,22 @@
|
||||
from ament_index_python.packages import get_package_share_directory
|
||||
|
||||
from launch import LaunchDescription
|
||||
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, OpaqueFunction
|
||||
from launch.actions import AppendEnvironmentVariable, DeclareLaunchArgument, IncludeLaunchDescription, OpaqueFunction
|
||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||||
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||
from launch_ros.substitutions import FindPackageShare
|
||||
|
||||
import os
|
||||
|
||||
ROS_DISTRO = os.environ.get('ROS_DISTRO')
|
||||
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
if not 'TURTLEBOT3_MODEL' in os.environ:
|
||||
os.environ['TURTLEBOT3_MODEL'] = 'waffle'
|
||||
|
||||
# Directories
|
||||
pkg_turtlebot3_gazebo = get_package_share_directory(
|
||||
'turtlebot3_gazebo')
|
||||
pkg_nav2_bringup = get_package_share_directory(
|
||||
'nav2_bringup')
|
||||
pkg_rtabmap_demos = get_package_share_directory(
|
||||
@@ -37,14 +41,26 @@ def launch_setup(context, *args, **kwargs):
|
||||
icp_odometry = icp_odometry == 'True' or icp_odometry == 'true'
|
||||
if icp_odometry:
|
||||
# modified nav2 params to use icp_odom instead odom frame
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_scan_nav2_params.yaml']
|
||||
)
|
||||
if ROS_DISTRO == 'humble':
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'humble', 'turtlebot3_scan_nav2_params.yaml']
|
||||
)
|
||||
else:
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_scan_nav2_params.yaml']
|
||||
)
|
||||
else:
|
||||
# original nav2 params
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('nav2_bringup'), 'params', 'nav2_params.yaml']
|
||||
)
|
||||
if ROS_DISTRO == 'humble':
|
||||
# original nav2 params
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('nav2_bringup'), 'params', 'nav2_params.yaml']
|
||||
)
|
||||
else:
|
||||
# original nav2 params but with "enable_stamped_cmd_vel: True"
|
||||
nav2_params_file = PathJoinSubstitution(
|
||||
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_nav2_params.yaml']
|
||||
)
|
||||
|
||||
|
||||
# Paths
|
||||
nav2_launch = PathJoinSubstitution(
|
||||
@@ -53,56 +69,6 @@ def launch_setup(context, *args, **kwargs):
|
||||
[pkg_nav2_bringup, 'launch', 'rviz_launch.py'])
|
||||
rtabmap_launch = PathJoinSubstitution(
|
||||
[pkg_rtabmap_demos, 'launch', 'turtlebot3', 'turtlebot3_scan.launch.py'])
|
||||
|
||||
# To use ICP odometry, we should increase clock rate of gazebo, we copied content of
|
||||
# turtlebot3_gazebo/launch/turtlebot3_world.launch here
|
||||
launch_file_dir = os.path.join(get_package_share_directory('turtlebot3_gazebo'), 'launch')
|
||||
pkg_gazebo_ros = get_package_share_directory('gazebo_ros')
|
||||
|
||||
world = os.path.join(
|
||||
get_package_share_directory('turtlebot3_gazebo'),
|
||||
'worlds',
|
||||
f'turtlebot3_{world_name}.world'
|
||||
)
|
||||
|
||||
import tempfile
|
||||
with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as clock_override_file:
|
||||
clock_override_file.write("---\n"+
|
||||
"gazebo:\n"+
|
||||
" ros__parameters:\n"+
|
||||
" publish_rate: 100.0")
|
||||
|
||||
gzserver_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_gazebo_ros, 'launch', 'gzserver.launch.py')
|
||||
),
|
||||
launch_arguments={
|
||||
'world': world,
|
||||
'params_file': clock_override_file.name}.items()
|
||||
)
|
||||
|
||||
gzclient_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_gazebo_ros, 'launch', 'gzclient.launch.py')
|
||||
)
|
||||
)
|
||||
|
||||
robot_state_publisher_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(launch_file_dir, 'robot_state_publisher.launch.py')
|
||||
),
|
||||
launch_arguments={'use_sim_time': 'true'}.items()
|
||||
)
|
||||
|
||||
spawn_turtlebot_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(launch_file_dir, 'spawn_turtlebot3.launch.py')
|
||||
),
|
||||
launch_arguments={
|
||||
'x_pose': LaunchConfiguration('x_pose'),
|
||||
'y_pose': LaunchConfiguration('y_pose')
|
||||
}.items()
|
||||
)
|
||||
|
||||
nav2 = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([nav2_launch]),
|
||||
@@ -121,16 +87,83 @@ def launch_setup(context, *args, **kwargs):
|
||||
('use_sim_time', 'true')
|
||||
]
|
||||
)
|
||||
|
||||
# To use ICP odometry, we should increase clock rate of gazebo (humble), we copied content of
|
||||
# turtlebot3_gazebo/launch/turtlebot3_world.launch here.
|
||||
turtlebot3_nodes = []
|
||||
if ROS_DISTRO == 'humble':
|
||||
pkg_gazebo_ros = get_package_share_directory('gazebo_ros')
|
||||
|
||||
import tempfile
|
||||
with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as clock_override_file:
|
||||
clock_override_file.write("---\n"+
|
||||
"gazebo:\n"+
|
||||
" ros__parameters:\n"+
|
||||
" publish_rate: 100.0")
|
||||
|
||||
world = os.path.join(
|
||||
pkg_turtlebot3_gazebo,
|
||||
'worlds',
|
||||
f'turtlebot3_{world_name}.world'
|
||||
)
|
||||
|
||||
gzserver_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_gazebo_ros, 'launch', 'gzserver.launch.py')
|
||||
),
|
||||
launch_arguments={
|
||||
'world': world,
|
||||
'params_file': clock_override_file.name}.items()
|
||||
)
|
||||
|
||||
gzclient_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_gazebo_ros, 'launch', 'gzclient.launch.py')
|
||||
)
|
||||
)
|
||||
|
||||
robot_state_publisher_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_turtlebot3_gazebo, 'launch', 'robot_state_publisher.launch.py')
|
||||
),
|
||||
launch_arguments={'use_sim_time': 'true'}.items()
|
||||
)
|
||||
spawn_turtlebot_cmd = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
os.path.join(pkg_turtlebot3_gazebo, 'launch', 'spawn_turtlebot3.launch.py')
|
||||
),
|
||||
launch_arguments={
|
||||
'x_pose': LaunchConfiguration('x_pose'),
|
||||
'y_pose': LaunchConfiguration('y_pose')
|
||||
}.items()
|
||||
)
|
||||
|
||||
set_env_vars_resources = AppendEnvironmentVariable(
|
||||
'GZ_SIM_RESOURCE_PATH',
|
||||
os.path.join(pkg_turtlebot3_gazebo, 'models'))
|
||||
turtlebot3_nodes = [
|
||||
gzserver_cmd,
|
||||
gzclient_cmd,
|
||||
robot_state_publisher_cmd,
|
||||
spawn_turtlebot_cmd,
|
||||
set_env_vars_resources
|
||||
]
|
||||
else:
|
||||
gazebo_launch = PathJoinSubstitution([pkg_turtlebot3_gazebo, 'launch', f'turtlebot3_{world_name}.launch.py'])
|
||||
gazebo = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([gazebo_launch]),
|
||||
launch_arguments=[
|
||||
('x_pose', LaunchConfiguration('x_pose')),
|
||||
('y_pose', LaunchConfiguration('y_pose'))
|
||||
]
|
||||
)
|
||||
turtlebot3_nodes = [gazebo]
|
||||
|
||||
return [
|
||||
# Nodes to launch
|
||||
nav2,
|
||||
rviz,
|
||||
rtabmap,
|
||||
gzserver_cmd,
|
||||
gzclient_cmd,
|
||||
robot_state_publisher_cmd,
|
||||
spawn_turtlebot_cmd
|
||||
]
|
||||
rtabmap] + turtlebot3_nodes
|
||||
|
||||
def generate_launch_description():
|
||||
return LaunchDescription([
|
||||
|
||||
@@ -114,6 +114,7 @@ def generate_launch_description():
|
||||
Node(
|
||||
condition=IfCondition(rtabmap_viz),
|
||||
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
|
||||
parameters=[rtabmap_parameters, shared_parameters],
|
||||
parameters=[rtabmap_parameters, shared_parameters,
|
||||
{"odometry_node_name": 'icp_odometry'}],
|
||||
remappings=remappings),
|
||||
])
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="3">
|
||||
<name>rtabmap_demos</name>
|
||||
<version>0.22.1</version>
|
||||
<version>0.23.7</version>
|
||||
<description>RTAB-Map's demo launch files.</description>
|
||||
<maintainer email="[email protected]">Mathieu Labbe</maintainer>
|
||||
<author>Mathieu Labbe</author>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# FusionCore config for TurtleBot3 Waffle (Gazebo Harmonic)
|
||||
#
|
||||
# Platform: TurtleBot3 Waffle (simulated)
|
||||
# IMU: MPU9250 (9-axis, magnetometer unreliable in sim)
|
||||
# GPS: None (indoor / simulation)
|
||||
# LiDAR: HLS-LFCD2 via /scan (used by icp_odometry, not fused here directly)
|
||||
# encoder2: rtabmap icp_odometry output on /rtabmap/icp_odometry
|
||||
#
|
||||
# Architecture: FusionCore (wheels + IMU) provides the odom frame.
|
||||
# icp_odometry uses that odom frame as its initial scan-matching guess
|
||||
# (guess_frame_id: odom). The ICP output feeds back into FusionCore
|
||||
# as a second velocity source (encoder2). Each tightens the other.
|
||||
|
||||
fusioncore:
|
||||
ros__parameters:
|
||||
base_frame: base_footprint
|
||||
odom_frame: odom
|
||||
publish_rate: 100.0
|
||||
publish.force_2d: true
|
||||
|
||||
# Gazebo Harmonic prefixes sensor frames with the model name (waffle/imu_link/tb3_imu).
|
||||
# Override to the TF frame that robot_state_publisher actually publishes.
|
||||
imu.frame_id: "imu_link"
|
||||
|
||||
# MPU9250: magnetometer disabled (unreliable in sim / near motors)
|
||||
imu.has_magnetometer: false
|
||||
# Simulation-tuned noise values for Gazebo Harmonic MPU9250 plugin.
|
||||
# Real MPU9250 hardware: gyro ~0.005 rad/s, accel ~0.1 m/s2.
|
||||
# Gazebo injects lower noise than the real sensor, so tighter values
|
||||
# reduce unnecessary filter uncertainty in sim without affecting real-hardware users
|
||||
# (who should revert to the hardware spec values above).
|
||||
imu.gyro_noise: 0.002 # rad/s (Gazebo sim-tuned; real MPU9250: 0.005)
|
||||
imu.accel_noise: 0.02 # m/s2 (Gazebo sim-tuned; real MPU9250: 0.1)
|
||||
imu.remove_gravitational_acceleration: false
|
||||
|
||||
# Wheel odometry noise (TB3 differential drive, simulated)
|
||||
encoder.vel_noise: 0.05 # m/s
|
||||
encoder.yaw_noise: 0.02 # rad/s
|
||||
|
||||
# ICP odometry as second velocity source
|
||||
encoder2.topic: "/rtabmap/icp_odometry"
|
||||
|
||||
outlier_rejection: true
|
||||
outlier_threshold_imu: 15.09
|
||||
outlier_threshold_enc: 11.34
|
||||
|
||||
adaptive.imu: true
|
||||
adaptive.encoder: true
|
||||
adaptive.window: 50
|
||||
adaptive.alpha: 0.01
|
||||
|
||||
zupt.enabled: true
|
||||
zupt.velocity_threshold: 0.08 # m/s: slightly loose for ICP jitter
|
||||
zupt.angular_threshold: 0.05 # rad/s
|
||||
zupt.noise_sigma: 0.01
|
||||
|
||||
ukf.q_position: 0.01
|
||||
ukf.q_orientation: 1.0e-9
|
||||
ukf.q_velocity: 0.1
|
||||
ukf.q_angular_vel: 0.1
|
||||
ukf.q_acceleration: 1.0
|
||||
ukf.q_gyro_bias: 1.0e-5
|
||||
ukf.q_accel_bias: 1.0e-5
|
||||
@@ -0,0 +1,47 @@
|
||||
# ros_gz_bridge config for the FusionCore + icp_odometry demo.
|
||||
#
|
||||
# Identical to turtlebot3_waffle_bridge.yaml EXCEPT the 'tf' entry is removed.
|
||||
# FusionCore publishes odom -> base_footprint TF directly, so the DiffDrive
|
||||
# plugin's TF must not be forwarded to avoid a competing transform.
|
||||
|
||||
- ros_topic_name: "clock"
|
||||
gz_topic_name: "clock"
|
||||
ros_type_name: "rosgraph_msgs/msg/Clock"
|
||||
gz_type_name: "gz.msgs.Clock"
|
||||
direction: GZ_TO_ROS
|
||||
|
||||
- ros_topic_name: "joint_states"
|
||||
gz_topic_name: "joint_states"
|
||||
ros_type_name: "sensor_msgs/msg/JointState"
|
||||
gz_type_name: "gz.msgs.Model"
|
||||
direction: GZ_TO_ROS
|
||||
|
||||
- ros_topic_name: "odom"
|
||||
gz_topic_name: "odom"
|
||||
ros_type_name: "nav_msgs/msg/Odometry"
|
||||
gz_type_name: "gz.msgs.Odometry"
|
||||
direction: GZ_TO_ROS
|
||||
|
||||
- ros_topic_name: "cmd_vel"
|
||||
gz_topic_name: "cmd_vel"
|
||||
ros_type_name: "geometry_msgs/msg/TwistStamped"
|
||||
gz_type_name: "gz.msgs.Twist"
|
||||
direction: ROS_TO_GZ
|
||||
|
||||
- ros_topic_name: "imu"
|
||||
gz_topic_name: "imu"
|
||||
ros_type_name: "sensor_msgs/msg/Imu"
|
||||
gz_type_name: "gz.msgs.IMU"
|
||||
direction: GZ_TO_ROS
|
||||
|
||||
- ros_topic_name: "scan"
|
||||
gz_topic_name: "scan"
|
||||
ros_type_name: "sensor_msgs/msg/LaserScan"
|
||||
gz_type_name: "gz.msgs.LaserScan"
|
||||
direction: GZ_TO_ROS
|
||||
|
||||
- ros_topic_name: "camera/camera_info"
|
||||
gz_topic_name: "camera/camera_info"
|
||||
ros_type_name: "sensor_msgs/msg/CameraInfo"
|
||||
gz_type_name: "gz.msgs.CameraInfo"
|
||||
direction: GZ_TO_ROS
|
||||
@@ -0,0 +1,287 @@
|
||||
# rtabmap_demos: We add segmented ground and obstacles to voxel_layer of the local costmap and removed scan source.
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
odom_topic: /odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
|
||||
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
|
||||
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
|
||||
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
|
||||
plugin_lib_names:
|
||||
- nav2_compute_path_to_pose_action_bt_node
|
||||
- nav2_compute_path_through_poses_action_bt_node
|
||||
- nav2_smooth_path_action_bt_node
|
||||
- nav2_follow_path_action_bt_node
|
||||
- nav2_spin_action_bt_node
|
||||
- nav2_wait_action_bt_node
|
||||
- nav2_assisted_teleop_action_bt_node
|
||||
- nav2_back_up_action_bt_node
|
||||
- nav2_drive_on_heading_bt_node
|
||||
- nav2_clear_costmap_service_bt_node
|
||||
- nav2_is_stuck_condition_bt_node
|
||||
- nav2_goal_reached_condition_bt_node
|
||||
- nav2_goal_updated_condition_bt_node
|
||||
- nav2_globally_updated_goal_condition_bt_node
|
||||
- nav2_is_path_valid_condition_bt_node
|
||||
- nav2_initial_pose_received_condition_bt_node
|
||||
- nav2_reinitialize_global_localization_service_bt_node
|
||||
- nav2_rate_controller_bt_node
|
||||
- nav2_distance_controller_bt_node
|
||||
- nav2_speed_controller_bt_node
|
||||
- nav2_truncate_path_action_bt_node
|
||||
- nav2_truncate_path_local_action_bt_node
|
||||
- nav2_goal_updater_node_bt_node
|
||||
- nav2_recovery_node_bt_node
|
||||
- nav2_pipeline_sequence_bt_node
|
||||
- nav2_round_robin_node_bt_node
|
||||
- nav2_transform_available_condition_bt_node
|
||||
- nav2_time_expired_condition_bt_node
|
||||
- nav2_path_expiring_timer_condition
|
||||
- nav2_distance_traveled_condition_bt_node
|
||||
- nav2_single_trigger_bt_node
|
||||
- nav2_goal_updated_controller_bt_node
|
||||
- nav2_is_battery_low_condition_bt_node
|
||||
- nav2_navigate_through_poses_action_bt_node
|
||||
- nav2_navigate_to_pose_action_bt_node
|
||||
- nav2_remove_passed_goals_action_bt_node
|
||||
- nav2_planner_selector_bt_node
|
||||
- nav2_controller_selector_bt_node
|
||||
- nav2_goal_checker_selector_bt_node
|
||||
- nav2_controller_cancel_bt_node
|
||||
- nav2_path_longer_on_approach_bt_node
|
||||
- nav2_wait_cancel_bt_node
|
||||
- nav2_spin_cancel_bt_node
|
||||
- nav2_back_up_cancel_bt_node
|
||||
- nav2_assisted_teleop_cancel_bt_node
|
||||
- nav2_drive_on_heading_cancel_bt_node
|
||||
- nav2_is_battery_charging_condition_bt_node
|
||||
|
||||
bt_navigator_navigate_through_poses_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
bt_navigator_navigate_to_pose_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
controller_frequency: 20.0
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
progress_checker_plugin: "progress_checker"
|
||||
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
|
||||
controller_plugins: ["FollowPath"]
|
||||
|
||||
# Progress checker parameters
|
||||
progress_checker:
|
||||
plugin: "nav2_controller::SimpleProgressChecker"
|
||||
required_movement_radius: 0.5
|
||||
movement_time_allowance: 10.0
|
||||
# Goal checker parameters
|
||||
#precise_goal_checker:
|
||||
# plugin: "nav2_controller::SimpleGoalChecker"
|
||||
# xy_goal_tolerance: 0.25
|
||||
# yaw_goal_tolerance: 0.25
|
||||
# stateful: True
|
||||
general_goal_checker:
|
||||
stateful: True
|
||||
plugin: "nav2_controller::SimpleGoalChecker"
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
# DWB parameters
|
||||
FollowPath:
|
||||
plugin: "dwb_core::DWBLocalPlanner"
|
||||
debug_trajectory_details: True
|
||||
min_vel_x: 0.0
|
||||
min_vel_y: 0.0
|
||||
max_vel_x: 0.26
|
||||
max_vel_y: 0.0
|
||||
max_vel_theta: 1.0
|
||||
min_speed_xy: 0.0
|
||||
max_speed_xy: 0.26
|
||||
min_speed_theta: 0.0
|
||||
# Add high threshold velocity for turtlebot 3 issue.
|
||||
# https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
|
||||
acc_lim_x: 2.5
|
||||
acc_lim_y: 0.0
|
||||
acc_lim_theta: 3.2
|
||||
decel_lim_x: -2.5
|
||||
decel_lim_y: 0.0
|
||||
decel_lim_theta: -3.2
|
||||
vx_samples: 20
|
||||
vy_samples: 5
|
||||
vtheta_samples: 20
|
||||
sim_time: 1.7
|
||||
linear_granularity: 0.05
|
||||
angular_granularity: 0.025
|
||||
transform_tolerance: 0.2
|
||||
xy_goal_tolerance: 0.25
|
||||
trans_stopped_velocity: 0.25
|
||||
short_circuit_trajectory_evaluation: True
|
||||
stateful: True
|
||||
critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
|
||||
BaseObstacle.scale: 0.02
|
||||
PathAlign.scale: 32.0
|
||||
PathAlign.forward_point_distance: 0.1
|
||||
GoalAlign.scale: 24.0
|
||||
GoalAlign.forward_point_distance: 0.1
|
||||
PathDist.scale: 32.0
|
||||
GoalDist.scale: 24.0
|
||||
RotateToGoal.scale: 32.0
|
||||
RotateToGoal.slowing_factor: 5.0
|
||||
RotateToGoal.lookahead_time: -1.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 5.0
|
||||
publish_frequency: 2.0
|
||||
global_frame: odom
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
resolution: 0.05
|
||||
robot_radius: 0.22
|
||||
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: ground obstacles
|
||||
ground:
|
||||
topic: /camera/ground
|
||||
max_obstacle_height: 0.4
|
||||
clearing: True
|
||||
marking: False
|
||||
data_type: "PointCloud2"
|
||||
raytrace_max_range: 3.0
|
||||
raytrace_min_range: 0.0
|
||||
obstacle_max_range: 2.5
|
||||
obstacle_min_range: 0.0
|
||||
obstacles:
|
||||
topic: /camera/obstacles
|
||||
max_obstacle_height: 0.4
|
||||
clearing: True
|
||||
marking: True
|
||||
data_type: "PointCloud2"
|
||||
raytrace_max_range: 3.0
|
||||
raytrace_min_range: 0.0
|
||||
obstacle_max_range: 2.5
|
||||
obstacle_min_range: 0.0
|
||||
static_layer:
|
||||
plugin: "nav2_costmap_2d::StaticLayer"
|
||||
map_subscribe_transient_local: True
|
||||
always_send_full_costmap: True
|
||||
|
||||
global_costmap:
|
||||
global_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 1.0
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
robot_radius: 0.22
|
||||
resolution: 0.05
|
||||
track_unknown_space: true
|
||||
plugins: ["static_layer", "inflation_layer"]
|
||||
static_layer:
|
||||
plugin: "nav2_costmap_2d::StaticLayer"
|
||||
map_subscribe_transient_local: True
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
always_send_full_costmap: True
|
||||
|
||||
map_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
# Overridden in launch by the "map" launch configuration or provided default value.
|
||||
# To use in yaml, remove the default "map" value in the tb3_simulation_launch.py file & provide full path to map below.
|
||||
yaml_filename: ""
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoother_plugins: ["simple_smoother"]
|
||||
simple_smoother:
|
||||
plugin: "nav2_smoother::SimpleSmoother"
|
||||
tolerance: 1.0e-10
|
||||
max_its: 1000
|
||||
do_refinement: True
|
||||
|
||||
behavior_server:
|
||||
ros__parameters:
|
||||
costmap_topic: local_costmap/costmap_raw
|
||||
footprint_topic: local_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
|
||||
spin:
|
||||
plugin: "nav2_behaviors/Spin"
|
||||
backup:
|
||||
plugin: "nav2_behaviors/BackUp"
|
||||
drive_on_heading:
|
||||
plugin: "nav2_behaviors/DriveOnHeading"
|
||||
wait:
|
||||
plugin: "nav2_behaviors/Wait"
|
||||
assisted_teleop:
|
||||
plugin: "nav2_behaviors/AssistedTeleop"
|
||||
global_frame: odom
|
||||
robot_base_frame: base_link
|
||||
transform_tolerance: 0.1
|
||||
use_sim_time: true
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
robot_state_publisher:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
waypoint_follower:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
loop_rate: 20
|
||||
stop_on_failure: false
|
||||
waypoint_task_executor_plugin: "wait_at_waypoint"
|
||||
wait_at_waypoint:
|
||||
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
|
||||
enabled: True
|
||||
waypoint_pause_duration: 200
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoothing_frequency: 20.0
|
||||
scale_velocities: False
|
||||
feedback: "OPEN_LOOP"
|
||||
max_velocity: [0.26, 0.0, 1.0]
|
||||
min_velocity: [-0.26, 0.0, -1.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: "odom"
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
@@ -0,0 +1,301 @@
|
||||
# rtabmap_demos: We add segmented ground and obstacles to voxel_layer of the local costmap.
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
odom_topic: /odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
|
||||
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
|
||||
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
|
||||
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
|
||||
plugin_lib_names:
|
||||
- nav2_compute_path_to_pose_action_bt_node
|
||||
- nav2_compute_path_through_poses_action_bt_node
|
||||
- nav2_smooth_path_action_bt_node
|
||||
- nav2_follow_path_action_bt_node
|
||||
- nav2_spin_action_bt_node
|
||||
- nav2_wait_action_bt_node
|
||||
- nav2_assisted_teleop_action_bt_node
|
||||
- nav2_back_up_action_bt_node
|
||||
- nav2_drive_on_heading_bt_node
|
||||
- nav2_clear_costmap_service_bt_node
|
||||
- nav2_is_stuck_condition_bt_node
|
||||
- nav2_goal_reached_condition_bt_node
|
||||
- nav2_goal_updated_condition_bt_node
|
||||
- nav2_globally_updated_goal_condition_bt_node
|
||||
- nav2_is_path_valid_condition_bt_node
|
||||
- nav2_initial_pose_received_condition_bt_node
|
||||
- nav2_reinitialize_global_localization_service_bt_node
|
||||
- nav2_rate_controller_bt_node
|
||||
- nav2_distance_controller_bt_node
|
||||
- nav2_speed_controller_bt_node
|
||||
- nav2_truncate_path_action_bt_node
|
||||
- nav2_truncate_path_local_action_bt_node
|
||||
- nav2_goal_updater_node_bt_node
|
||||
- nav2_recovery_node_bt_node
|
||||
- nav2_pipeline_sequence_bt_node
|
||||
- nav2_round_robin_node_bt_node
|
||||
- nav2_transform_available_condition_bt_node
|
||||
- nav2_time_expired_condition_bt_node
|
||||
- nav2_path_expiring_timer_condition
|
||||
- nav2_distance_traveled_condition_bt_node
|
||||
- nav2_single_trigger_bt_node
|
||||
- nav2_goal_updated_controller_bt_node
|
||||
- nav2_is_battery_low_condition_bt_node
|
||||
- nav2_navigate_through_poses_action_bt_node
|
||||
- nav2_navigate_to_pose_action_bt_node
|
||||
- nav2_remove_passed_goals_action_bt_node
|
||||
- nav2_planner_selector_bt_node
|
||||
- nav2_controller_selector_bt_node
|
||||
- nav2_goal_checker_selector_bt_node
|
||||
- nav2_controller_cancel_bt_node
|
||||
- nav2_path_longer_on_approach_bt_node
|
||||
- nav2_wait_cancel_bt_node
|
||||
- nav2_spin_cancel_bt_node
|
||||
- nav2_back_up_cancel_bt_node
|
||||
- nav2_assisted_teleop_cancel_bt_node
|
||||
- nav2_drive_on_heading_cancel_bt_node
|
||||
- nav2_is_battery_charging_condition_bt_node
|
||||
|
||||
bt_navigator_navigate_through_poses_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
bt_navigator_navigate_to_pose_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
controller_frequency: 20.0
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
progress_checker_plugin: "progress_checker"
|
||||
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
|
||||
controller_plugins: ["FollowPath"]
|
||||
|
||||
# Progress checker parameters
|
||||
progress_checker:
|
||||
plugin: "nav2_controller::SimpleProgressChecker"
|
||||
required_movement_radius: 0.5
|
||||
movement_time_allowance: 10.0
|
||||
# Goal checker parameters
|
||||
#precise_goal_checker:
|
||||
# plugin: "nav2_controller::SimpleGoalChecker"
|
||||
# xy_goal_tolerance: 0.25
|
||||
# yaw_goal_tolerance: 0.25
|
||||
# stateful: True
|
||||
general_goal_checker:
|
||||
stateful: True
|
||||
plugin: "nav2_controller::SimpleGoalChecker"
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
# DWB parameters
|
||||
FollowPath:
|
||||
plugin: "dwb_core::DWBLocalPlanner"
|
||||
debug_trajectory_details: True
|
||||
min_vel_x: 0.0
|
||||
min_vel_y: 0.0
|
||||
max_vel_x: 0.26
|
||||
max_vel_y: 0.0
|
||||
max_vel_theta: 1.0
|
||||
min_speed_xy: 0.0
|
||||
max_speed_xy: 0.26
|
||||
min_speed_theta: 0.0
|
||||
# Add high threshold velocity for turtlebot 3 issue.
|
||||
# https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
|
||||
acc_lim_x: 2.5
|
||||
acc_lim_y: 0.0
|
||||
acc_lim_theta: 3.2
|
||||
decel_lim_x: -2.5
|
||||
decel_lim_y: 0.0
|
||||
decel_lim_theta: -3.2
|
||||
vx_samples: 20
|
||||
vy_samples: 5
|
||||
vtheta_samples: 20
|
||||
sim_time: 1.7
|
||||
linear_granularity: 0.05
|
||||
angular_granularity: 0.025
|
||||
transform_tolerance: 0.2
|
||||
xy_goal_tolerance: 0.25
|
||||
trans_stopped_velocity: 0.25
|
||||
short_circuit_trajectory_evaluation: True
|
||||
stateful: True
|
||||
critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
|
||||
BaseObstacle.scale: 0.02
|
||||
PathAlign.scale: 32.0
|
||||
PathAlign.forward_point_distance: 0.1
|
||||
GoalAlign.scale: 24.0
|
||||
GoalAlign.forward_point_distance: 0.1
|
||||
PathDist.scale: 32.0
|
||||
GoalDist.scale: 24.0
|
||||
RotateToGoal.scale: 32.0
|
||||
RotateToGoal.slowing_factor: 5.0
|
||||
RotateToGoal.lookahead_time: -1.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 5.0
|
||||
publish_frequency: 2.0
|
||||
global_frame: odom
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
resolution: 0.05
|
||||
robot_radius: 0.22
|
||||
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 ground obstacles
|
||||
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
|
||||
ground:
|
||||
topic: /camera/ground
|
||||
max_obstacle_height: 0.4
|
||||
clearing: True
|
||||
marking: False
|
||||
data_type: "PointCloud2"
|
||||
raytrace_max_range: 3.0
|
||||
raytrace_min_range: 0.0
|
||||
obstacle_max_range: 2.5
|
||||
obstacle_min_range: 0.0
|
||||
obstacles:
|
||||
topic: /camera/obstacles
|
||||
max_obstacle_height: 0.4
|
||||
clearing: True
|
||||
marking: True
|
||||
data_type: "PointCloud2"
|
||||
raytrace_max_range: 3.0
|
||||
raytrace_min_range: 0.0
|
||||
obstacle_max_range: 2.5
|
||||
obstacle_min_range: 0.0
|
||||
static_layer:
|
||||
plugin: "nav2_costmap_2d::StaticLayer"
|
||||
map_subscribe_transient_local: True
|
||||
always_send_full_costmap: True
|
||||
|
||||
global_costmap:
|
||||
global_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 1.0
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
robot_radius: 0.22
|
||||
resolution: 0.05
|
||||
track_unknown_space: true
|
||||
plugins: ["static_layer", "inflation_layer"]
|
||||
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
|
||||
|
||||
planner_server:
|
||||
ros__parameters:
|
||||
expected_planner_frequency: 20.0
|
||||
use_sim_time: True
|
||||
planner_plugins: ["GridBased"]
|
||||
GridBased:
|
||||
plugin: "nav2_navfn_planner/NavfnPlanner"
|
||||
tolerance: 0.5
|
||||
use_astar: false
|
||||
allow_unknown: true
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoother_plugins: ["simple_smoother"]
|
||||
simple_smoother:
|
||||
plugin: "nav2_smoother::SimpleSmoother"
|
||||
tolerance: 1.0e-10
|
||||
max_its: 1000
|
||||
do_refinement: True
|
||||
|
||||
behavior_server:
|
||||
ros__parameters:
|
||||
costmap_topic: local_costmap/costmap_raw
|
||||
footprint_topic: local_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
|
||||
spin:
|
||||
plugin: "nav2_behaviors/Spin"
|
||||
backup:
|
||||
plugin: "nav2_behaviors/BackUp"
|
||||
drive_on_heading:
|
||||
plugin: "nav2_behaviors/DriveOnHeading"
|
||||
wait:
|
||||
plugin: "nav2_behaviors/Wait"
|
||||
assisted_teleop:
|
||||
plugin: "nav2_behaviors/AssistedTeleop"
|
||||
global_frame: odom
|
||||
robot_base_frame: base_link
|
||||
transform_tolerance: 0.1
|
||||
use_sim_time: true
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
robot_state_publisher:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
waypoint_follower:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
loop_rate: 20
|
||||
stop_on_failure: false
|
||||
waypoint_task_executor_plugin: "wait_at_waypoint"
|
||||
wait_at_waypoint:
|
||||
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
|
||||
enabled: True
|
||||
waypoint_pause_duration: 200
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoothing_frequency: 20.0
|
||||
scale_velocities: False
|
||||
feedback: "OPEN_LOOP"
|
||||
max_velocity: [0.26, 0.0, 1.0]
|
||||
min_velocity: [-0.26, 0.0, -1.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: "odom"
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
@@ -0,0 +1,295 @@
|
||||
# Modified to use icp_odom frame
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
odom_topic: /odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
|
||||
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
|
||||
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
|
||||
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
|
||||
plugin_lib_names:
|
||||
- nav2_compute_path_to_pose_action_bt_node
|
||||
- nav2_compute_path_through_poses_action_bt_node
|
||||
- nav2_smooth_path_action_bt_node
|
||||
- nav2_follow_path_action_bt_node
|
||||
- nav2_spin_action_bt_node
|
||||
- nav2_wait_action_bt_node
|
||||
- nav2_assisted_teleop_action_bt_node
|
||||
- nav2_back_up_action_bt_node
|
||||
- nav2_drive_on_heading_bt_node
|
||||
- nav2_clear_costmap_service_bt_node
|
||||
- nav2_is_stuck_condition_bt_node
|
||||
- nav2_goal_reached_condition_bt_node
|
||||
- nav2_goal_updated_condition_bt_node
|
||||
- nav2_globally_updated_goal_condition_bt_node
|
||||
- nav2_is_path_valid_condition_bt_node
|
||||
- nav2_initial_pose_received_condition_bt_node
|
||||
- nav2_reinitialize_global_localization_service_bt_node
|
||||
- nav2_rate_controller_bt_node
|
||||
- nav2_distance_controller_bt_node
|
||||
- nav2_speed_controller_bt_node
|
||||
- nav2_truncate_path_action_bt_node
|
||||
- nav2_truncate_path_local_action_bt_node
|
||||
- nav2_goal_updater_node_bt_node
|
||||
- nav2_recovery_node_bt_node
|
||||
- nav2_pipeline_sequence_bt_node
|
||||
- nav2_round_robin_node_bt_node
|
||||
- nav2_transform_available_condition_bt_node
|
||||
- nav2_time_expired_condition_bt_node
|
||||
- nav2_path_expiring_timer_condition
|
||||
- nav2_distance_traveled_condition_bt_node
|
||||
- nav2_single_trigger_bt_node
|
||||
- nav2_goal_updated_controller_bt_node
|
||||
- nav2_is_battery_low_condition_bt_node
|
||||
- nav2_navigate_through_poses_action_bt_node
|
||||
- nav2_navigate_to_pose_action_bt_node
|
||||
- nav2_remove_passed_goals_action_bt_node
|
||||
- nav2_planner_selector_bt_node
|
||||
- nav2_controller_selector_bt_node
|
||||
- nav2_goal_checker_selector_bt_node
|
||||
- nav2_controller_cancel_bt_node
|
||||
- nav2_path_longer_on_approach_bt_node
|
||||
- nav2_wait_cancel_bt_node
|
||||
- nav2_spin_cancel_bt_node
|
||||
- nav2_back_up_cancel_bt_node
|
||||
- nav2_assisted_teleop_cancel_bt_node
|
||||
- nav2_drive_on_heading_cancel_bt_node
|
||||
- nav2_is_battery_charging_condition_bt_node
|
||||
|
||||
bt_navigator_navigate_through_poses_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
bt_navigator_navigate_to_pose_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
controller_frequency: 20.0
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
progress_checker_plugin: "progress_checker"
|
||||
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
|
||||
controller_plugins: ["FollowPath"]
|
||||
|
||||
# Progress checker parameters
|
||||
progress_checker:
|
||||
plugin: "nav2_controller::SimpleProgressChecker"
|
||||
required_movement_radius: 0.5
|
||||
movement_time_allowance: 10.0
|
||||
# Goal checker parameters
|
||||
#precise_goal_checker:
|
||||
# plugin: "nav2_controller::SimpleGoalChecker"
|
||||
# xy_goal_tolerance: 0.25
|
||||
# yaw_goal_tolerance: 0.25
|
||||
# stateful: True
|
||||
general_goal_checker:
|
||||
stateful: True
|
||||
plugin: "nav2_controller::SimpleGoalChecker"
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
# DWB parameters
|
||||
FollowPath:
|
||||
plugin: "dwb_core::DWBLocalPlanner"
|
||||
debug_trajectory_details: True
|
||||
min_vel_x: 0.0
|
||||
min_vel_y: 0.0
|
||||
max_vel_x: 0.26
|
||||
max_vel_y: 0.0
|
||||
max_vel_theta: 1.0
|
||||
min_speed_xy: 0.0
|
||||
max_speed_xy: 0.26
|
||||
min_speed_theta: 0.0
|
||||
# Add high threshold velocity for turtlebot 3 issue.
|
||||
# https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
|
||||
acc_lim_x: 2.5
|
||||
acc_lim_y: 0.0
|
||||
acc_lim_theta: 3.2
|
||||
decel_lim_x: -2.5
|
||||
decel_lim_y: 0.0
|
||||
decel_lim_theta: -3.2
|
||||
vx_samples: 20
|
||||
vy_samples: 5
|
||||
vtheta_samples: 20
|
||||
sim_time: 1.7
|
||||
linear_granularity: 0.05
|
||||
angular_granularity: 0.025
|
||||
transform_tolerance: 0.2
|
||||
xy_goal_tolerance: 0.25
|
||||
trans_stopped_velocity: 0.25
|
||||
short_circuit_trajectory_evaluation: True
|
||||
stateful: True
|
||||
critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
|
||||
BaseObstacle.scale: 0.02
|
||||
PathAlign.scale: 32.0
|
||||
PathAlign.forward_point_distance: 0.1
|
||||
GoalAlign.scale: 24.0
|
||||
GoalAlign.forward_point_distance: 0.1
|
||||
PathDist.scale: 32.0
|
||||
GoalDist.scale: 24.0
|
||||
RotateToGoal.scale: 32.0
|
||||
RotateToGoal.slowing_factor: 5.0
|
||||
RotateToGoal.lookahead_time: -1.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 5.0
|
||||
publish_frequency: 2.0
|
||||
global_frame: icp_odom
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
resolution: 0.05
|
||||
robot_radius: 0.22
|
||||
plugins: ["voxel_layer", "inflation_layer"]
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
voxel_layer:
|
||||
plugin: "nav2_costmap_2d::VoxelLayer"
|
||||
enabled: True
|
||||
publish_voxel_map: True
|
||||
origin_z: 0.0
|
||||
z_resolution: 0.05
|
||||
z_voxels: 16
|
||||
max_obstacle_height: 2.0
|
||||
mark_threshold: 0
|
||||
observation_sources: scan
|
||||
scan:
|
||||
topic: /scan
|
||||
max_obstacle_height: 2.0
|
||||
clearing: True
|
||||
marking: True
|
||||
data_type: "LaserScan"
|
||||
raytrace_max_range: 3.0
|
||||
raytrace_min_range: 0.0
|
||||
obstacle_max_range: 2.5
|
||||
obstacle_min_range: 0.0
|
||||
static_layer:
|
||||
plugin: "nav2_costmap_2d::StaticLayer"
|
||||
map_subscribe_transient_local: True
|
||||
always_send_full_costmap: True
|
||||
|
||||
global_costmap:
|
||||
global_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 1.0
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
robot_radius: 0.22
|
||||
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
|
||||
|
||||
planner_server:
|
||||
ros__parameters:
|
||||
expected_planner_frequency: 20.0
|
||||
use_sim_time: True
|
||||
planner_plugins: ["GridBased"]
|
||||
GridBased:
|
||||
plugin: "nav2_navfn_planner/NavfnPlanner"
|
||||
tolerance: 0.5
|
||||
use_astar: false
|
||||
allow_unknown: true
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoother_plugins: ["simple_smoother"]
|
||||
simple_smoother:
|
||||
plugin: "nav2_smoother::SimpleSmoother"
|
||||
tolerance: 1.0e-10
|
||||
max_its: 1000
|
||||
do_refinement: True
|
||||
|
||||
behavior_server:
|
||||
ros__parameters:
|
||||
costmap_topic: local_costmap/costmap_raw
|
||||
footprint_topic: local_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
|
||||
spin:
|
||||
plugin: "nav2_behaviors/Spin"
|
||||
backup:
|
||||
plugin: "nav2_behaviors/BackUp"
|
||||
drive_on_heading:
|
||||
plugin: "nav2_behaviors/DriveOnHeading"
|
||||
wait:
|
||||
plugin: "nav2_behaviors/Wait"
|
||||
assisted_teleop:
|
||||
plugin: "nav2_behaviors/AssistedTeleop"
|
||||
global_frame: icp_odom
|
||||
robot_base_frame: base_link
|
||||
transform_tolerance: 0.1
|
||||
use_sim_time: true
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
robot_state_publisher:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
waypoint_follower:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
loop_rate: 20
|
||||
stop_on_failure: false
|
||||
waypoint_task_executor_plugin: "wait_at_waypoint"
|
||||
wait_at_waypoint:
|
||||
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
|
||||
enabled: True
|
||||
waypoint_pause_duration: 200
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoothing_frequency: 20.0
|
||||
scale_velocities: False
|
||||
feedback: "OPEN_LOOP"
|
||||
max_velocity: [0.26, 0.0, 1.0]
|
||||
min_velocity: [-0.26, 0.0, -1.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: "odom"
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
@@ -0,0 +1,280 @@
|
||||
# Nav2 parameters for FusionCore + icp_odometry TurtleBot3 demo.
|
||||
#
|
||||
# Key difference from stock nav2 params:
|
||||
# - odom_topic: /fusion/odom (FusionCore output, not /odom or /odometry/filtered)
|
||||
# - No AMCL: rtabmap handles the map -> odom transform via its SLAM output.
|
||||
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
global_frame: map
|
||||
robot_base_frame: base_footprint
|
||||
odom_topic: /fusion/odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
action_server_result_timeout: 900.0
|
||||
navigators: ['navigate_to_pose', 'navigate_through_poses']
|
||||
navigate_to_pose:
|
||||
plugin: 'nav2_bt_navigator::NavigateToPoseNavigator'
|
||||
navigate_through_poses:
|
||||
plugin: 'nav2_bt_navigator::NavigateThroughPosesNavigator'
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 20.0
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
odom_topic: /fusion/odom
|
||||
progress_checker_plugins: ['progress_checker']
|
||||
goal_checker_plugins: ['general_goal_checker']
|
||||
controller_plugins: ['FollowPath']
|
||||
progress_checker:
|
||||
plugin: 'nav2_controller::SimpleProgressChecker'
|
||||
required_movement_radius: 0.5
|
||||
movement_time_allowance: 10.0
|
||||
general_goal_checker:
|
||||
stateful: true
|
||||
plugin: 'nav2_controller::SimpleGoalChecker'
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
FollowPath:
|
||||
plugin: 'nav2_regulated_pure_pursuit_controller::RegulatedPurePursuitController'
|
||||
desired_linear_vel: 0.2
|
||||
lookahead_dist: 0.6
|
||||
min_lookahead_dist: 0.3
|
||||
max_lookahead_dist: 0.9
|
||||
lookahead_time: 1.5
|
||||
rotate_to_heading_angular_vel: 1.8
|
||||
transform_tolerance: 0.1
|
||||
use_velocity_scaled_lookahead_dist: false
|
||||
min_approach_linear_velocity: 0.05
|
||||
approach_velocity_scaling_dist: 0.6
|
||||
use_collision_detection: true
|
||||
max_allowed_time_to_collision_up_to_goal: 1.0
|
||||
use_regulated_linear_velocity_scaling: true
|
||||
use_fixed_curvature_lookahead: false
|
||||
curvature_feedforward_gain: 1.0
|
||||
use_cost_regulated_linear_velocity_scaling: false
|
||||
regulated_linear_scaling_min_radius: 0.9
|
||||
regulated_linear_scaling_min_speed: 0.25
|
||||
use_rotate_to_heading: true
|
||||
allow_reversing: false
|
||||
rotate_to_heading_min_angle: 0.785
|
||||
max_angular_accel: 3.2
|
||||
max_robot_pose_search_dist: 10.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
update_frequency: 5.0
|
||||
publish_frequency: 2.0
|
||||
global_frame: odom
|
||||
robot_base_frame: base_footprint
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
resolution: 0.05
|
||||
robot_radius: 0.22
|
||||
plugins: ['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
|
||||
inflation_layer:
|
||||
plugin: 'nav2_costmap_2d::InflationLayer'
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
always_send_full_costmap: true
|
||||
|
||||
global_costmap:
|
||||
global_costmap:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
update_frequency: 1.0
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_footprint
|
||||
robot_radius: 0.22
|
||||
resolution: 0.05
|
||||
track_unknown_space: true
|
||||
plugins: ['static_layer', 'obstacle_layer', 'inflation_layer']
|
||||
static_layer:
|
||||
plugin: 'nav2_costmap_2d::StaticLayer'
|
||||
map_subscribe_transient_local: true
|
||||
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
|
||||
inflation_layer:
|
||||
plugin: 'nav2_costmap_2d::InflationLayer'
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
always_send_full_costmap: true
|
||||
|
||||
planner_server:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
expected_planner_frequency: 20.0
|
||||
planner_plugins: ['GridBased']
|
||||
GridBased:
|
||||
plugin: 'nav2_navfn_planner::NavfnPlanner'
|
||||
tolerance: 0.5
|
||||
use_astar: false
|
||||
allow_unknown: true
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
enable_stamped_cmd_vel: 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:
|
||||
use_sim_time: true
|
||||
enable_stamped_cmd_vel: True
|
||||
local_costmap_topic: local_costmap/costmap_raw
|
||||
global_costmap_topic: global_costmap/costmap_raw
|
||||
local_footprint_topic: local_costmap/published_footprint
|
||||
global_footprint_topic: global_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ['spin', 'backup', 'drive_on_heading', 'assisted_teleop', 'wait']
|
||||
spin:
|
||||
plugin: 'nav2_behaviors::Spin'
|
||||
backup:
|
||||
plugin: 'nav2_behaviors::BackUp'
|
||||
drive_on_heading:
|
||||
plugin: 'nav2_behaviors::DriveOnHeading'
|
||||
wait:
|
||||
plugin: 'nav2_behaviors::Wait'
|
||||
assisted_teleop:
|
||||
plugin: 'nav2_behaviors::AssistedTeleop'
|
||||
local_frame: odom
|
||||
global_frame: map
|
||||
robot_base_frame: base_footprint
|
||||
transform_tolerance: 0.1
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
enable_stamped_cmd_vel: True
|
||||
smoothing_frequency: 20.0
|
||||
scale_velocities: false
|
||||
feedback: 'OPEN_LOOP'
|
||||
max_velocity: [0.26, 0.0, 1.0]
|
||||
min_velocity: [-0.26, 0.0, -1.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: /fusion/odom
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
|
||||
collision_monitor:
|
||||
ros__parameters:
|
||||
use_sim_time: true
|
||||
enable_stamped_cmd_vel: True
|
||||
base_frame_id: base_footprint
|
||||
odom_frame_id: odom
|
||||
cmd_vel_in_topic: cmd_vel_smoothed
|
||||
cmd_vel_out_topic: cmd_vel
|
||||
state_topic: collision_monitor_state
|
||||
transform_error_pub_topic: transform_error
|
||||
polygons: ['FootprintApproach']
|
||||
FootprintApproach:
|
||||
type: polygon
|
||||
action_type: approach
|
||||
footprint_topic: local_costmap/published_footprint
|
||||
time_before_collision: 1.2
|
||||
simulation_time_step: 0.1
|
||||
min_points: 6
|
||||
visualize: false
|
||||
enabled: true
|
||||
observation_sources: ['scan']
|
||||
scan:
|
||||
type: scan
|
||||
topic: /scan
|
||||
min_height: 0.15
|
||||
max_height: 2.0
|
||||
enabled: true
|
||||
|
||||
|
||||
docking_server:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 50.0
|
||||
initial_perception_timeout: 5.0
|
||||
wait_charge_timeout: 5.0
|
||||
dock_approach_timeout: 30.0
|
||||
undock_linear_tolerance: 0.05
|
||||
undock_angular_tolerance: 0.1
|
||||
max_retries: 3
|
||||
base_frame: "base_footprint"
|
||||
fixed_frame: "odom"
|
||||
dock_backwards: false
|
||||
dock_prestaging_tolerance: 0.5
|
||||
|
||||
# Types of docks
|
||||
dock_plugins: ['simple_charging_dock']
|
||||
simple_charging_dock:
|
||||
plugin: 'opennav_docking::SimpleChargingDock'
|
||||
docking_threshold: 0.05
|
||||
staging_x_offset: -0.7
|
||||
use_external_detection_pose: true
|
||||
use_battery_status: false # true
|
||||
use_stall_detection: false # true
|
||||
|
||||
external_detection_timeout: 1.0
|
||||
external_detection_translation_x: -0.18
|
||||
external_detection_translation_y: 0.0
|
||||
external_detection_rotation_roll: -1.57
|
||||
external_detection_rotation_pitch: -1.57
|
||||
external_detection_rotation_yaw: 0.0
|
||||
filter_coef: 0.1
|
||||
|
||||
controller:
|
||||
k_phi: 3.0
|
||||
k_delta: 2.0
|
||||
v_linear_min: 0.15
|
||||
v_linear_max: 0.15
|
||||
use_collision_detection: true
|
||||
costmap_topic: "local_costmap/costmap_raw"
|
||||
footprint_topic: "local_costmap/published_footprint"
|
||||
transform_tolerance: 0.1
|
||||
projection_time: 5.0
|
||||
simulation_step: 0.1
|
||||
dock_collision_threshold: 0.3
|
||||
@@ -0,0 +1,421 @@
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
odom_topic: /odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
action_server_result_timeout: 900.0
|
||||
navigators: ["navigate_to_pose", "navigate_through_poses"]
|
||||
navigate_to_pose:
|
||||
plugin: "nav2_bt_navigator::NavigateToPoseNavigator"
|
||||
navigate_through_poses:
|
||||
plugin: "nav2_bt_navigator::NavigateThroughPosesNavigator"
|
||||
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
|
||||
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
|
||||
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
|
||||
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
|
||||
|
||||
# plugin_lib_names is used to add custom BT plugins to the executor (vector of strings).
|
||||
# Built-in plugins are added automatically
|
||||
# plugin_lib_names: []
|
||||
|
||||
error_code_names:
|
||||
- compute_path_error_code
|
||||
- follow_path_error_code
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 20.0
|
||||
costmap_update_timeout: 0.30
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
progress_checker_plugins: ["progress_checker"]
|
||||
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
|
||||
controller_plugins: ["FollowPath"]
|
||||
use_realtime_priority: false
|
||||
|
||||
# Progress checker parameters
|
||||
progress_checker:
|
||||
plugin: "nav2_controller::SimpleProgressChecker"
|
||||
required_movement_radius: 0.5
|
||||
movement_time_allowance: 10.0
|
||||
# Goal checker parameters
|
||||
#precise_goal_checker:
|
||||
# plugin: "nav2_controller::SimpleGoalChecker"
|
||||
# xy_goal_tolerance: 0.25
|
||||
# yaw_goal_tolerance: 0.25
|
||||
# stateful: True
|
||||
general_goal_checker:
|
||||
stateful: True
|
||||
plugin: "nav2_controller::SimpleGoalChecker"
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
FollowPath:
|
||||
plugin: "nav2_mppi_controller::MPPIController"
|
||||
time_steps: 56
|
||||
model_dt: 0.05
|
||||
batch_size: 2000
|
||||
ax_max: 3.0
|
||||
ax_min: -3.0
|
||||
ay_max: 3.0
|
||||
ay_min: -3.0
|
||||
az_max: 3.5
|
||||
vx_std: 0.2
|
||||
vy_std: 0.2
|
||||
wz_std: 0.4
|
||||
vx_max: 0.5
|
||||
vx_min: -0.35
|
||||
vy_max: 0.5
|
||||
wz_max: 1.9
|
||||
iteration_count: 1
|
||||
prune_distance: 1.7
|
||||
transform_tolerance: 0.1
|
||||
temperature: 0.3
|
||||
gamma: 0.015
|
||||
motion_model: "DiffDrive"
|
||||
visualize: true
|
||||
regenerate_noises: true
|
||||
TrajectoryVisualizer:
|
||||
trajectory_step: 5
|
||||
time_step: 3
|
||||
AckermannConstraints:
|
||||
min_turning_r: 0.2
|
||||
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
|
||||
near_collision_cost: 253
|
||||
critical_cost: 300.0
|
||||
consider_footprint: false
|
||||
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
|
||||
mode: 0
|
||||
# TwirlingCritic:
|
||||
# enabled: true
|
||||
# twirling_cost_power: 1
|
||||
# twirling_cost_weight: 10.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 5.0
|
||||
publish_frequency: 2.0
|
||||
global_frame: odom
|
||||
robot_base_frame: base_link
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
resolution: 0.05
|
||||
robot_radius: 0.22
|
||||
plugins: ["voxel_layer", "inflation_layer"]
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.70
|
||||
voxel_layer:
|
||||
plugin: "nav2_costmap_2d::VoxelLayer"
|
||||
enabled: True
|
||||
publish_voxel_map: True
|
||||
origin_z: 0.0
|
||||
z_resolution: 0.05
|
||||
z_voxels: 16
|
||||
max_obstacle_height: 2.0
|
||||
mark_threshold: 0
|
||||
observation_sources: scan
|
||||
scan:
|
||||
topic: /scan
|
||||
max_obstacle_height: 2.0
|
||||
clearing: True
|
||||
marking: True
|
||||
data_type: "LaserScan"
|
||||
raytrace_max_range: 3.0
|
||||
raytrace_min_range: 0.0
|
||||
obstacle_max_range: 2.5
|
||||
obstacle_min_range: 0.0
|
||||
static_layer:
|
||||
plugin: "nav2_costmap_2d::StaticLayer"
|
||||
map_subscribe_transient_local: True
|
||||
always_send_full_costmap: True
|
||||
|
||||
global_costmap:
|
||||
global_costmap:
|
||||
ros__parameters:
|
||||
update_frequency: 1.0
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
robot_radius: 0.22
|
||||
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.7
|
||||
always_send_full_costmap: True
|
||||
|
||||
planner_server:
|
||||
ros__parameters:
|
||||
expected_planner_frequency: 20.0
|
||||
planner_plugins: ["GridBased"]
|
||||
costmap_update_timeout: 1.0
|
||||
GridBased:
|
||||
plugin: "nav2_navfn_planner::NavfnPlanner"
|
||||
tolerance: 0.5
|
||||
use_astar: false
|
||||
allow_unknown: true
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
smoother_plugins: ["simple_smoother"]
|
||||
simple_smoother:
|
||||
plugin: "nav2_smoother::SimpleSmoother"
|
||||
tolerance: 1.0e-10
|
||||
max_its: 1000
|
||||
do_refinement: True
|
||||
|
||||
behavior_server:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
local_costmap_topic: local_costmap/costmap_raw
|
||||
global_costmap_topic: global_costmap/costmap_raw
|
||||
local_footprint_topic: local_costmap/published_footprint
|
||||
global_footprint_topic: global_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
|
||||
spin:
|
||||
plugin: "nav2_behaviors::Spin"
|
||||
backup:
|
||||
plugin: "nav2_behaviors::BackUp"
|
||||
drive_on_heading:
|
||||
plugin: "nav2_behaviors::DriveOnHeading"
|
||||
wait:
|
||||
plugin: "nav2_behaviors::Wait"
|
||||
assisted_teleop:
|
||||
plugin: "nav2_behaviors::AssistedTeleop"
|
||||
local_frame: odom
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
transform_tolerance: 0.1
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
waypoint_follower:
|
||||
ros__parameters:
|
||||
loop_rate: 20
|
||||
stop_on_failure: false
|
||||
action_server_result_timeout: 900.0
|
||||
waypoint_task_executor_plugin: "wait_at_waypoint"
|
||||
wait_at_waypoint:
|
||||
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
|
||||
enabled: True
|
||||
waypoint_pause_duration: 200
|
||||
|
||||
route_server:
|
||||
ros__parameters:
|
||||
# The graph_filepath does not need to be specified since it going to be set by defaults in launch.
|
||||
# If you'd rather set it in the yaml, remove the default "graph" value in the launch file(s).
|
||||
# file & provide full path to map below. If graph config or launch default is provided, it is used
|
||||
# graph_filepath: $(find-pkg-share nav2_route)/graphs/aws_graph.geojson
|
||||
boundary_radius_to_achieve_node: 1.0
|
||||
radius_to_achieve_node: 2.0
|
||||
smooth_corners: true
|
||||
operations: ["AdjustSpeedLimit", "ReroutingService", "CollisionMonitor"]
|
||||
ReroutingService:
|
||||
plugin: "nav2_route::ReroutingService"
|
||||
AdjustSpeedLimit:
|
||||
plugin: "nav2_route::AdjustSpeedLimit"
|
||||
CollisionMonitor:
|
||||
plugin: "nav2_route::CollisionMonitor"
|
||||
max_collision_dist: 3.0
|
||||
edge_cost_functions: ["DistanceScorer", "CostmapScorer"]
|
||||
DistanceScorer:
|
||||
plugin: "nav2_route::DistanceScorer"
|
||||
CostmapScorer:
|
||||
plugin: "nav2_route::CostmapScorer"
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
smoothing_frequency: 20.0
|
||||
stamp_smoothed_velocity_with_smoothing_time: False
|
||||
scale_velocities: False
|
||||
feedback: "OPEN_LOOP"
|
||||
max_velocity: [0.5, 0.0, 2.0]
|
||||
min_velocity: [-0.5, 0.0, -2.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: "odom"
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
|
||||
collision_monitor:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "odom"
|
||||
cmd_vel_in_topic: "cmd_vel_smoothed"
|
||||
cmd_vel_out_topic: "cmd_vel"
|
||||
state_topic: "collision_monitor_state"
|
||||
transform_tolerance: 0.2
|
||||
source_timeout: 1.0
|
||||
base_shift_correction: True
|
||||
stop_pub_timeout: 2.0
|
||||
# Polygons represent zone around the robot for "stop", "slowdown" and "limit" action types,
|
||||
# and robot footprint for "approach" action type.
|
||||
polygons: ["FootprintApproach"]
|
||||
FootprintApproach:
|
||||
type: "polygon"
|
||||
action_type: "approach"
|
||||
footprint_topic: "/local_costmap/published_footprint"
|
||||
time_before_collision: 1.2
|
||||
simulation_time_step: 0.1
|
||||
min_points: 6
|
||||
visualize: False
|
||||
enabled: True
|
||||
observation_sources: ["scan"]
|
||||
scan:
|
||||
type: "scan"
|
||||
topic: "scan"
|
||||
min_height: 0.15
|
||||
max_height: 2.0
|
||||
enabled: True
|
||||
|
||||
docking_server:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 50.0
|
||||
initial_perception_timeout: 5.0
|
||||
wait_charge_timeout: 5.0
|
||||
dock_approach_timeout: 30.0
|
||||
undock_linear_tolerance: 0.05
|
||||
undock_angular_tolerance: 0.1
|
||||
max_retries: 3
|
||||
base_frame: "base_link"
|
||||
fixed_frame: "odom"
|
||||
dock_backwards: false
|
||||
dock_prestaging_tolerance: 0.5
|
||||
|
||||
# Types of docks
|
||||
dock_plugins: ['simple_charging_dock']
|
||||
simple_charging_dock:
|
||||
plugin: 'opennav_docking::SimpleChargingDock'
|
||||
docking_threshold: 0.05
|
||||
staging_x_offset: -0.7
|
||||
use_external_detection_pose: true
|
||||
use_battery_status: false # true
|
||||
use_stall_detection: false # true
|
||||
|
||||
external_detection_timeout: 1.0
|
||||
external_detection_translation_x: -0.18
|
||||
external_detection_translation_y: 0.0
|
||||
external_detection_rotation_roll: -1.57
|
||||
external_detection_rotation_pitch: -1.57
|
||||
external_detection_rotation_yaw: 0.0
|
||||
filter_coef: 0.1
|
||||
|
||||
# Dock instances
|
||||
# The following example illustrates configuring dock instances.
|
||||
# docks: ['home_dock'] # Input your docks here
|
||||
# home_dock:
|
||||
# type: 'simple_charging_dock'
|
||||
# frame: map
|
||||
# pose: [0.0, 0.0, 0.0]
|
||||
|
||||
controller:
|
||||
k_phi: 3.0
|
||||
k_delta: 2.0
|
||||
v_linear_min: 0.15
|
||||
v_linear_max: 0.15
|
||||
use_collision_detection: true
|
||||
costmap_topic: "local_costmap/costmap_raw"
|
||||
footprint_topic: "local_costmap/published_footprint"
|
||||
transform_tolerance: 0.1
|
||||
projection_time: 5.0
|
||||
simulation_step: 0.1
|
||||
dock_collision_threshold: 0.3
|
||||
|
||||
loopback_simulator:
|
||||
ros__parameters:
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "odom"
|
||||
map_frame_id: "map"
|
||||
scan_frame_id: "base_scan" # tb4_loopback_simulator.launch.py remaps to 'rplidar_link'
|
||||
update_duration: 0.02
|
||||
scan_range_min: 0.05
|
||||
scan_range_max: 30.0
|
||||
scan_angle_min: -3.1415
|
||||
scan_angle_max: 3.1415
|
||||
scan_angle_increment: 0.02617
|
||||
scan_use_inf: true
|
||||
@@ -1,85 +1,44 @@
|
||||
# rtabmap_demos: We add segmented ground and obstacles to voxel_layer of the local costmap and removed scan source.
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
odom_topic: /odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
action_server_result_timeout: 900.0
|
||||
navigators: ["navigate_to_pose", "navigate_through_poses"]
|
||||
navigate_to_pose:
|
||||
plugin: "nav2_bt_navigator::NavigateToPoseNavigator"
|
||||
navigate_through_poses:
|
||||
plugin: "nav2_bt_navigator::NavigateThroughPosesNavigator"
|
||||
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
|
||||
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
|
||||
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
|
||||
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
|
||||
plugin_lib_names:
|
||||
- nav2_compute_path_to_pose_action_bt_node
|
||||
- nav2_compute_path_through_poses_action_bt_node
|
||||
- nav2_smooth_path_action_bt_node
|
||||
- nav2_follow_path_action_bt_node
|
||||
- nav2_spin_action_bt_node
|
||||
- nav2_wait_action_bt_node
|
||||
- nav2_assisted_teleop_action_bt_node
|
||||
- nav2_back_up_action_bt_node
|
||||
- nav2_drive_on_heading_bt_node
|
||||
- nav2_clear_costmap_service_bt_node
|
||||
- nav2_is_stuck_condition_bt_node
|
||||
- nav2_goal_reached_condition_bt_node
|
||||
- nav2_goal_updated_condition_bt_node
|
||||
- nav2_globally_updated_goal_condition_bt_node
|
||||
- nav2_is_path_valid_condition_bt_node
|
||||
- nav2_initial_pose_received_condition_bt_node
|
||||
- nav2_reinitialize_global_localization_service_bt_node
|
||||
- nav2_rate_controller_bt_node
|
||||
- nav2_distance_controller_bt_node
|
||||
- nav2_speed_controller_bt_node
|
||||
- nav2_truncate_path_action_bt_node
|
||||
- nav2_truncate_path_local_action_bt_node
|
||||
- nav2_goal_updater_node_bt_node
|
||||
- nav2_recovery_node_bt_node
|
||||
- nav2_pipeline_sequence_bt_node
|
||||
- nav2_round_robin_node_bt_node
|
||||
- nav2_transform_available_condition_bt_node
|
||||
- nav2_time_expired_condition_bt_node
|
||||
- nav2_path_expiring_timer_condition
|
||||
- nav2_distance_traveled_condition_bt_node
|
||||
- nav2_single_trigger_bt_node
|
||||
- nav2_goal_updated_controller_bt_node
|
||||
- nav2_is_battery_low_condition_bt_node
|
||||
- nav2_navigate_through_poses_action_bt_node
|
||||
- nav2_navigate_to_pose_action_bt_node
|
||||
- nav2_remove_passed_goals_action_bt_node
|
||||
- nav2_planner_selector_bt_node
|
||||
- nav2_controller_selector_bt_node
|
||||
- nav2_goal_checker_selector_bt_node
|
||||
- nav2_controller_cancel_bt_node
|
||||
- nav2_path_longer_on_approach_bt_node
|
||||
- nav2_wait_cancel_bt_node
|
||||
- nav2_spin_cancel_bt_node
|
||||
- nav2_back_up_cancel_bt_node
|
||||
- nav2_assisted_teleop_cancel_bt_node
|
||||
- nav2_drive_on_heading_cancel_bt_node
|
||||
- nav2_is_battery_charging_condition_bt_node
|
||||
|
||||
bt_navigator_navigate_through_poses_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
# plugin_lib_names is used to add custom BT plugins to the executor (vector of strings).
|
||||
# Built-in plugins are added automatically
|
||||
# plugin_lib_names: []
|
||||
|
||||
bt_navigator_navigate_to_pose_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
error_code_names:
|
||||
- compute_path_error_code
|
||||
- follow_path_error_code
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 20.0
|
||||
costmap_update_timeout: 0.30
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
progress_checker_plugin: "progress_checker"
|
||||
progress_checker_plugins: ["progress_checker"]
|
||||
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
|
||||
controller_plugins: ["FollowPath"]
|
||||
use_realtime_priority: false
|
||||
|
||||
# Progress checker parameters
|
||||
progress_checker:
|
||||
@@ -97,48 +56,96 @@ controller_server:
|
||||
plugin: "nav2_controller::SimpleGoalChecker"
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
# DWB parameters
|
||||
FollowPath:
|
||||
plugin: "dwb_core::DWBLocalPlanner"
|
||||
debug_trajectory_details: True
|
||||
min_vel_x: 0.0
|
||||
min_vel_y: 0.0
|
||||
max_vel_x: 0.26
|
||||
max_vel_y: 0.0
|
||||
max_vel_theta: 1.0
|
||||
min_speed_xy: 0.0
|
||||
max_speed_xy: 0.26
|
||||
min_speed_theta: 0.0
|
||||
# Add high threshold velocity for turtlebot 3 issue.
|
||||
# https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
|
||||
acc_lim_x: 2.5
|
||||
acc_lim_y: 0.0
|
||||
acc_lim_theta: 3.2
|
||||
decel_lim_x: -2.5
|
||||
decel_lim_y: 0.0
|
||||
decel_lim_theta: -3.2
|
||||
vx_samples: 20
|
||||
vy_samples: 5
|
||||
vtheta_samples: 20
|
||||
sim_time: 1.7
|
||||
linear_granularity: 0.05
|
||||
angular_granularity: 0.025
|
||||
transform_tolerance: 0.2
|
||||
xy_goal_tolerance: 0.25
|
||||
trans_stopped_velocity: 0.25
|
||||
short_circuit_trajectory_evaluation: True
|
||||
stateful: True
|
||||
critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
|
||||
BaseObstacle.scale: 0.02
|
||||
PathAlign.scale: 32.0
|
||||
PathAlign.forward_point_distance: 0.1
|
||||
GoalAlign.scale: 24.0
|
||||
GoalAlign.forward_point_distance: 0.1
|
||||
PathDist.scale: 32.0
|
||||
GoalDist.scale: 24.0
|
||||
RotateToGoal.scale: 32.0
|
||||
RotateToGoal.slowing_factor: 5.0
|
||||
RotateToGoal.lookahead_time: -1.0
|
||||
plugin: "nav2_mppi_controller::MPPIController"
|
||||
time_steps: 56
|
||||
model_dt: 0.05
|
||||
batch_size: 2000
|
||||
ax_max: 3.0
|
||||
ax_min: -3.0
|
||||
ay_max: 3.0
|
||||
ay_min: -3.0
|
||||
az_max: 3.5
|
||||
vx_std: 0.2
|
||||
vy_std: 0.2
|
||||
wz_std: 0.4
|
||||
vx_max: 0.5
|
||||
vx_min: -0.35
|
||||
vy_max: 0.5
|
||||
wz_max: 1.9
|
||||
iteration_count: 1
|
||||
prune_distance: 1.7
|
||||
transform_tolerance: 0.1
|
||||
temperature: 0.3
|
||||
gamma: 0.015
|
||||
motion_model: "DiffDrive"
|
||||
visualize: true
|
||||
regenerate_noises: true
|
||||
TrajectoryVisualizer:
|
||||
trajectory_step: 5
|
||||
time_step: 3
|
||||
AckermannConstraints:
|
||||
min_turning_r: 0.2
|
||||
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
|
||||
near_collision_cost: 253
|
||||
critical_cost: 300.0
|
||||
consider_footprint: false
|
||||
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
|
||||
mode: 0
|
||||
# TwirlingCritic:
|
||||
# enabled: true
|
||||
# twirling_cost_power: 1
|
||||
# twirling_cost_weight: 10.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
@@ -147,7 +154,6 @@ local_costmap:
|
||||
publish_frequency: 2.0
|
||||
global_frame: odom
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
@@ -157,7 +163,7 @@ local_costmap:
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
inflation_radius: 0.70
|
||||
voxel_layer:
|
||||
plugin: "nav2_costmap_2d::VoxelLayer"
|
||||
enabled: True
|
||||
@@ -200,7 +206,6 @@ global_costmap:
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
robot_radius: 0.22
|
||||
resolution: 0.05
|
||||
track_unknown_space: true
|
||||
@@ -211,19 +216,22 @@ global_costmap:
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
inflation_radius: 0.7
|
||||
always_send_full_costmap: True
|
||||
|
||||
map_server:
|
||||
planner_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
# Overridden in launch by the "map" launch configuration or provided default value.
|
||||
# To use in yaml, remove the default "map" value in the tb3_simulation_launch.py file & provide full path to map below.
|
||||
yaml_filename: ""
|
||||
expected_planner_frequency: 20.0
|
||||
planner_plugins: ["GridBased"]
|
||||
costmap_update_timeout: 1.0
|
||||
GridBased:
|
||||
plugin: "nav2_navfn_planner::NavfnPlanner"
|
||||
tolerance: 0.5
|
||||
use_astar: false
|
||||
allow_unknown: true
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoother_plugins: ["simple_smoother"]
|
||||
simple_smoother:
|
||||
plugin: "nav2_smoother::SimpleSmoother"
|
||||
@@ -233,55 +241,178 @@ smoother_server:
|
||||
|
||||
behavior_server:
|
||||
ros__parameters:
|
||||
costmap_topic: local_costmap/costmap_raw
|
||||
footprint_topic: local_costmap/published_footprint
|
||||
enable_stamped_cmd_vel: True
|
||||
local_costmap_topic: local_costmap/costmap_raw
|
||||
global_costmap_topic: global_costmap/costmap_raw
|
||||
local_footprint_topic: local_costmap/published_footprint
|
||||
global_footprint_topic: global_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
|
||||
spin:
|
||||
plugin: "nav2_behaviors/Spin"
|
||||
plugin: "nav2_behaviors::Spin"
|
||||
backup:
|
||||
plugin: "nav2_behaviors/BackUp"
|
||||
plugin: "nav2_behaviors::BackUp"
|
||||
drive_on_heading:
|
||||
plugin: "nav2_behaviors/DriveOnHeading"
|
||||
plugin: "nav2_behaviors::DriveOnHeading"
|
||||
wait:
|
||||
plugin: "nav2_behaviors/Wait"
|
||||
plugin: "nav2_behaviors::Wait"
|
||||
assisted_teleop:
|
||||
plugin: "nav2_behaviors/AssistedTeleop"
|
||||
global_frame: odom
|
||||
plugin: "nav2_behaviors::AssistedTeleop"
|
||||
local_frame: odom
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
transform_tolerance: 0.1
|
||||
use_sim_time: true
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
robot_state_publisher:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
waypoint_follower:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
loop_rate: 20
|
||||
stop_on_failure: false
|
||||
action_server_result_timeout: 900.0
|
||||
waypoint_task_executor_plugin: "wait_at_waypoint"
|
||||
wait_at_waypoint:
|
||||
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
|
||||
enabled: True
|
||||
waypoint_pause_duration: 200
|
||||
|
||||
route_server:
|
||||
ros__parameters:
|
||||
# The graph_filepath does not need to be specified since it going to be set by defaults in launch.
|
||||
# If you'd rather set it in the yaml, remove the default "graph" value in the launch file(s).
|
||||
# file & provide full path to map below. If graph config or launch default is provided, it is used
|
||||
# graph_filepath: $(find-pkg-share nav2_route)/graphs/aws_graph.geojson
|
||||
boundary_radius_to_achieve_node: 1.0
|
||||
radius_to_achieve_node: 2.0
|
||||
smooth_corners: true
|
||||
operations: ["AdjustSpeedLimit", "ReroutingService", "CollisionMonitor"]
|
||||
ReroutingService:
|
||||
plugin: "nav2_route::ReroutingService"
|
||||
AdjustSpeedLimit:
|
||||
plugin: "nav2_route::AdjustSpeedLimit"
|
||||
CollisionMonitor:
|
||||
plugin: "nav2_route::CollisionMonitor"
|
||||
max_collision_dist: 3.0
|
||||
edge_cost_functions: ["DistanceScorer", "CostmapScorer"]
|
||||
DistanceScorer:
|
||||
plugin: "nav2_route::DistanceScorer"
|
||||
CostmapScorer:
|
||||
plugin: "nav2_route::CostmapScorer"
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
enable_stamped_cmd_vel: True
|
||||
smoothing_frequency: 20.0
|
||||
stamp_smoothed_velocity_with_smoothing_time: False
|
||||
scale_velocities: False
|
||||
feedback: "OPEN_LOOP"
|
||||
max_velocity: [0.26, 0.0, 1.0]
|
||||
min_velocity: [-0.26, 0.0, -1.0]
|
||||
max_velocity: [0.5, 0.0, 2.0]
|
||||
min_velocity: [-0.5, 0.0, -2.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: "odom"
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
|
||||
collision_monitor:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "odom"
|
||||
cmd_vel_in_topic: "cmd_vel_smoothed"
|
||||
cmd_vel_out_topic: "cmd_vel"
|
||||
state_topic: "collision_monitor_state"
|
||||
transform_tolerance: 0.2
|
||||
source_timeout: 1.0
|
||||
base_shift_correction: True
|
||||
stop_pub_timeout: 2.0
|
||||
# Polygons represent zone around the robot for "stop", "slowdown" and "limit" action types,
|
||||
# and robot footprint for "approach" action type.
|
||||
polygons: ["FootprintApproach"]
|
||||
FootprintApproach:
|
||||
type: "polygon"
|
||||
action_type: "approach"
|
||||
footprint_topic: "/local_costmap/published_footprint"
|
||||
time_before_collision: 1.2
|
||||
simulation_time_step: 0.1
|
||||
min_points: 6
|
||||
visualize: False
|
||||
enabled: True
|
||||
observation_sources: ["scan"]
|
||||
scan:
|
||||
type: "scan"
|
||||
topic: "scan"
|
||||
min_height: 0.15
|
||||
max_height: 2.0
|
||||
enabled: True
|
||||
|
||||
docking_server:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 50.0
|
||||
initial_perception_timeout: 5.0
|
||||
wait_charge_timeout: 5.0
|
||||
dock_approach_timeout: 30.0
|
||||
undock_linear_tolerance: 0.05
|
||||
undock_angular_tolerance: 0.1
|
||||
max_retries: 3
|
||||
base_frame: "base_link"
|
||||
fixed_frame: "odom"
|
||||
dock_backwards: false
|
||||
dock_prestaging_tolerance: 0.5
|
||||
|
||||
# Types of docks
|
||||
dock_plugins: ['simple_charging_dock']
|
||||
simple_charging_dock:
|
||||
plugin: 'opennav_docking::SimpleChargingDock'
|
||||
docking_threshold: 0.05
|
||||
staging_x_offset: -0.7
|
||||
use_external_detection_pose: true
|
||||
use_battery_status: false # true
|
||||
use_stall_detection: false # true
|
||||
|
||||
external_detection_timeout: 1.0
|
||||
external_detection_translation_x: -0.18
|
||||
external_detection_translation_y: 0.0
|
||||
external_detection_rotation_roll: -1.57
|
||||
external_detection_rotation_pitch: -1.57
|
||||
external_detection_rotation_yaw: 0.0
|
||||
filter_coef: 0.1
|
||||
|
||||
# Dock instances
|
||||
# The following example illustrates configuring dock instances.
|
||||
# docks: ['home_dock'] # Input your docks here
|
||||
# home_dock:
|
||||
# type: 'simple_charging_dock'
|
||||
# frame: map
|
||||
# pose: [0.0, 0.0, 0.0]
|
||||
|
||||
controller:
|
||||
k_phi: 3.0
|
||||
k_delta: 2.0
|
||||
v_linear_min: 0.15
|
||||
v_linear_max: 0.15
|
||||
use_collision_detection: true
|
||||
costmap_topic: "local_costmap/costmap_raw"
|
||||
footprint_topic: "local_costmap/published_footprint"
|
||||
transform_tolerance: 0.1
|
||||
projection_time: 5.0
|
||||
simulation_step: 0.1
|
||||
dock_collision_threshold: 0.3
|
||||
|
||||
loopback_simulator:
|
||||
ros__parameters:
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "odom"
|
||||
map_frame_id: "map"
|
||||
scan_frame_id: "base_scan" # tb4_loopback_simulator.launch.py remaps to 'rplidar_link'
|
||||
update_duration: 0.02
|
||||
scan_range_min: 0.05
|
||||
scan_range_max: 30.0
|
||||
scan_angle_min: -3.1415
|
||||
scan_angle_max: 3.1415
|
||||
scan_angle_increment: 0.02617
|
||||
scan_use_inf: true
|
||||
|
||||
@@ -1,85 +1,44 @@
|
||||
# rtabmap_demos: We add segmented ground and obstacles to voxel_layer of the local costmap.
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
odom_topic: /odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
action_server_result_timeout: 900.0
|
||||
navigators: ["navigate_to_pose", "navigate_through_poses"]
|
||||
navigate_to_pose:
|
||||
plugin: "nav2_bt_navigator::NavigateToPoseNavigator"
|
||||
navigate_through_poses:
|
||||
plugin: "nav2_bt_navigator::NavigateThroughPosesNavigator"
|
||||
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
|
||||
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
|
||||
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
|
||||
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
|
||||
plugin_lib_names:
|
||||
- nav2_compute_path_to_pose_action_bt_node
|
||||
- nav2_compute_path_through_poses_action_bt_node
|
||||
- nav2_smooth_path_action_bt_node
|
||||
- nav2_follow_path_action_bt_node
|
||||
- nav2_spin_action_bt_node
|
||||
- nav2_wait_action_bt_node
|
||||
- nav2_assisted_teleop_action_bt_node
|
||||
- nav2_back_up_action_bt_node
|
||||
- nav2_drive_on_heading_bt_node
|
||||
- nav2_clear_costmap_service_bt_node
|
||||
- nav2_is_stuck_condition_bt_node
|
||||
- nav2_goal_reached_condition_bt_node
|
||||
- nav2_goal_updated_condition_bt_node
|
||||
- nav2_globally_updated_goal_condition_bt_node
|
||||
- nav2_is_path_valid_condition_bt_node
|
||||
- nav2_initial_pose_received_condition_bt_node
|
||||
- nav2_reinitialize_global_localization_service_bt_node
|
||||
- nav2_rate_controller_bt_node
|
||||
- nav2_distance_controller_bt_node
|
||||
- nav2_speed_controller_bt_node
|
||||
- nav2_truncate_path_action_bt_node
|
||||
- nav2_truncate_path_local_action_bt_node
|
||||
- nav2_goal_updater_node_bt_node
|
||||
- nav2_recovery_node_bt_node
|
||||
- nav2_pipeline_sequence_bt_node
|
||||
- nav2_round_robin_node_bt_node
|
||||
- nav2_transform_available_condition_bt_node
|
||||
- nav2_time_expired_condition_bt_node
|
||||
- nav2_path_expiring_timer_condition
|
||||
- nav2_distance_traveled_condition_bt_node
|
||||
- nav2_single_trigger_bt_node
|
||||
- nav2_goal_updated_controller_bt_node
|
||||
- nav2_is_battery_low_condition_bt_node
|
||||
- nav2_navigate_through_poses_action_bt_node
|
||||
- nav2_navigate_to_pose_action_bt_node
|
||||
- nav2_remove_passed_goals_action_bt_node
|
||||
- nav2_planner_selector_bt_node
|
||||
- nav2_controller_selector_bt_node
|
||||
- nav2_goal_checker_selector_bt_node
|
||||
- nav2_controller_cancel_bt_node
|
||||
- nav2_path_longer_on_approach_bt_node
|
||||
- nav2_wait_cancel_bt_node
|
||||
- nav2_spin_cancel_bt_node
|
||||
- nav2_back_up_cancel_bt_node
|
||||
- nav2_assisted_teleop_cancel_bt_node
|
||||
- nav2_drive_on_heading_cancel_bt_node
|
||||
- nav2_is_battery_charging_condition_bt_node
|
||||
|
||||
bt_navigator_navigate_through_poses_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
# plugin_lib_names is used to add custom BT plugins to the executor (vector of strings).
|
||||
# Built-in plugins are added automatically
|
||||
# plugin_lib_names: []
|
||||
|
||||
bt_navigator_navigate_to_pose_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
error_code_names:
|
||||
- compute_path_error_code
|
||||
- follow_path_error_code
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 20.0
|
||||
costmap_update_timeout: 0.30
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
progress_checker_plugin: "progress_checker"
|
||||
progress_checker_plugins: ["progress_checker"]
|
||||
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
|
||||
controller_plugins: ["FollowPath"]
|
||||
use_realtime_priority: false
|
||||
|
||||
# Progress checker parameters
|
||||
progress_checker:
|
||||
@@ -97,48 +56,96 @@ controller_server:
|
||||
plugin: "nav2_controller::SimpleGoalChecker"
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
# DWB parameters
|
||||
FollowPath:
|
||||
plugin: "dwb_core::DWBLocalPlanner"
|
||||
debug_trajectory_details: True
|
||||
min_vel_x: 0.0
|
||||
min_vel_y: 0.0
|
||||
max_vel_x: 0.26
|
||||
max_vel_y: 0.0
|
||||
max_vel_theta: 1.0
|
||||
min_speed_xy: 0.0
|
||||
max_speed_xy: 0.26
|
||||
min_speed_theta: 0.0
|
||||
# Add high threshold velocity for turtlebot 3 issue.
|
||||
# https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
|
||||
acc_lim_x: 2.5
|
||||
acc_lim_y: 0.0
|
||||
acc_lim_theta: 3.2
|
||||
decel_lim_x: -2.5
|
||||
decel_lim_y: 0.0
|
||||
decel_lim_theta: -3.2
|
||||
vx_samples: 20
|
||||
vy_samples: 5
|
||||
vtheta_samples: 20
|
||||
sim_time: 1.7
|
||||
linear_granularity: 0.05
|
||||
angular_granularity: 0.025
|
||||
transform_tolerance: 0.2
|
||||
xy_goal_tolerance: 0.25
|
||||
trans_stopped_velocity: 0.25
|
||||
short_circuit_trajectory_evaluation: True
|
||||
stateful: True
|
||||
critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
|
||||
BaseObstacle.scale: 0.02
|
||||
PathAlign.scale: 32.0
|
||||
PathAlign.forward_point_distance: 0.1
|
||||
GoalAlign.scale: 24.0
|
||||
GoalAlign.forward_point_distance: 0.1
|
||||
PathDist.scale: 32.0
|
||||
GoalDist.scale: 24.0
|
||||
RotateToGoal.scale: 32.0
|
||||
RotateToGoal.slowing_factor: 5.0
|
||||
RotateToGoal.lookahead_time: -1.0
|
||||
plugin: "nav2_mppi_controller::MPPIController"
|
||||
time_steps: 56
|
||||
model_dt: 0.05
|
||||
batch_size: 2000
|
||||
ax_max: 3.0
|
||||
ax_min: -3.0
|
||||
ay_max: 3.0
|
||||
ay_min: -3.0
|
||||
az_max: 3.5
|
||||
vx_std: 0.2
|
||||
vy_std: 0.2
|
||||
wz_std: 0.4
|
||||
vx_max: 0.5
|
||||
vx_min: -0.35
|
||||
vy_max: 0.5
|
||||
wz_max: 1.9
|
||||
iteration_count: 1
|
||||
prune_distance: 1.7
|
||||
transform_tolerance: 0.1
|
||||
temperature: 0.3
|
||||
gamma: 0.015
|
||||
motion_model: "DiffDrive"
|
||||
visualize: true
|
||||
regenerate_noises: true
|
||||
TrajectoryVisualizer:
|
||||
trajectory_step: 5
|
||||
time_step: 3
|
||||
AckermannConstraints:
|
||||
min_turning_r: 0.2
|
||||
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
|
||||
near_collision_cost: 253
|
||||
critical_cost: 300.0
|
||||
consider_footprint: false
|
||||
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
|
||||
mode: 0
|
||||
# TwirlingCritic:
|
||||
# enabled: true
|
||||
# twirling_cost_power: 1
|
||||
# twirling_cost_weight: 10.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
@@ -147,7 +154,6 @@ local_costmap:
|
||||
publish_frequency: 2.0
|
||||
global_frame: odom
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
@@ -157,7 +163,7 @@ local_costmap:
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
inflation_radius: 0.70
|
||||
voxel_layer:
|
||||
plugin: "nav2_costmap_2d::VoxelLayer"
|
||||
enabled: True
|
||||
@@ -210,7 +216,6 @@ global_costmap:
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
robot_radius: 0.22
|
||||
resolution: 0.05
|
||||
track_unknown_space: true
|
||||
@@ -221,23 +226,22 @@ global_costmap:
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
inflation_radius: 0.7
|
||||
always_send_full_costmap: True
|
||||
|
||||
planner_server:
|
||||
ros__parameters:
|
||||
expected_planner_frequency: 20.0
|
||||
use_sim_time: True
|
||||
planner_plugins: ["GridBased"]
|
||||
costmap_update_timeout: 1.0
|
||||
GridBased:
|
||||
plugin: "nav2_navfn_planner/NavfnPlanner"
|
||||
plugin: "nav2_navfn_planner::NavfnPlanner"
|
||||
tolerance: 0.5
|
||||
use_astar: false
|
||||
allow_unknown: true
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoother_plugins: ["simple_smoother"]
|
||||
simple_smoother:
|
||||
plugin: "nav2_smoother::SimpleSmoother"
|
||||
@@ -247,55 +251,178 @@ smoother_server:
|
||||
|
||||
behavior_server:
|
||||
ros__parameters:
|
||||
costmap_topic: local_costmap/costmap_raw
|
||||
footprint_topic: local_costmap/published_footprint
|
||||
enable_stamped_cmd_vel: True
|
||||
local_costmap_topic: local_costmap/costmap_raw
|
||||
global_costmap_topic: global_costmap/costmap_raw
|
||||
local_footprint_topic: local_costmap/published_footprint
|
||||
global_footprint_topic: global_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
|
||||
spin:
|
||||
plugin: "nav2_behaviors/Spin"
|
||||
plugin: "nav2_behaviors::Spin"
|
||||
backup:
|
||||
plugin: "nav2_behaviors/BackUp"
|
||||
plugin: "nav2_behaviors::BackUp"
|
||||
drive_on_heading:
|
||||
plugin: "nav2_behaviors/DriveOnHeading"
|
||||
plugin: "nav2_behaviors::DriveOnHeading"
|
||||
wait:
|
||||
plugin: "nav2_behaviors/Wait"
|
||||
plugin: "nav2_behaviors::Wait"
|
||||
assisted_teleop:
|
||||
plugin: "nav2_behaviors/AssistedTeleop"
|
||||
global_frame: odom
|
||||
plugin: "nav2_behaviors::AssistedTeleop"
|
||||
local_frame: odom
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
transform_tolerance: 0.1
|
||||
use_sim_time: true
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
robot_state_publisher:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
waypoint_follower:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
loop_rate: 20
|
||||
stop_on_failure: false
|
||||
action_server_result_timeout: 900.0
|
||||
waypoint_task_executor_plugin: "wait_at_waypoint"
|
||||
wait_at_waypoint:
|
||||
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
|
||||
enabled: True
|
||||
waypoint_pause_duration: 200
|
||||
|
||||
route_server:
|
||||
ros__parameters:
|
||||
# The graph_filepath does not need to be specified since it going to be set by defaults in launch.
|
||||
# If you'd rather set it in the yaml, remove the default "graph" value in the launch file(s).
|
||||
# file & provide full path to map below. If graph config or launch default is provided, it is used
|
||||
# graph_filepath: $(find-pkg-share nav2_route)/graphs/aws_graph.geojson
|
||||
boundary_radius_to_achieve_node: 1.0
|
||||
radius_to_achieve_node: 2.0
|
||||
smooth_corners: true
|
||||
operations: ["AdjustSpeedLimit", "ReroutingService", "CollisionMonitor"]
|
||||
ReroutingService:
|
||||
plugin: "nav2_route::ReroutingService"
|
||||
AdjustSpeedLimit:
|
||||
plugin: "nav2_route::AdjustSpeedLimit"
|
||||
CollisionMonitor:
|
||||
plugin: "nav2_route::CollisionMonitor"
|
||||
max_collision_dist: 3.0
|
||||
edge_cost_functions: ["DistanceScorer", "CostmapScorer"]
|
||||
DistanceScorer:
|
||||
plugin: "nav2_route::DistanceScorer"
|
||||
CostmapScorer:
|
||||
plugin: "nav2_route::CostmapScorer"
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
enable_stamped_cmd_vel: True
|
||||
smoothing_frequency: 20.0
|
||||
stamp_smoothed_velocity_with_smoothing_time: False
|
||||
scale_velocities: False
|
||||
feedback: "OPEN_LOOP"
|
||||
max_velocity: [0.26, 0.0, 1.0]
|
||||
min_velocity: [-0.26, 0.0, -1.0]
|
||||
max_velocity: [0.5, 0.0, 2.0]
|
||||
min_velocity: [-0.5, 0.0, -2.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: "odom"
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
|
||||
collision_monitor:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "odom"
|
||||
cmd_vel_in_topic: "cmd_vel_smoothed"
|
||||
cmd_vel_out_topic: "cmd_vel"
|
||||
state_topic: "collision_monitor_state"
|
||||
transform_tolerance: 0.2
|
||||
source_timeout: 1.0
|
||||
base_shift_correction: True
|
||||
stop_pub_timeout: 2.0
|
||||
# Polygons represent zone around the robot for "stop", "slowdown" and "limit" action types,
|
||||
# and robot footprint for "approach" action type.
|
||||
polygons: ["FootprintApproach"]
|
||||
FootprintApproach:
|
||||
type: "polygon"
|
||||
action_type: "approach"
|
||||
footprint_topic: "/local_costmap/published_footprint"
|
||||
time_before_collision: 1.2
|
||||
simulation_time_step: 0.1
|
||||
min_points: 6
|
||||
visualize: False
|
||||
enabled: True
|
||||
observation_sources: ["scan"]
|
||||
scan:
|
||||
type: "scan"
|
||||
topic: "scan"
|
||||
min_height: 0.15
|
||||
max_height: 2.0
|
||||
enabled: True
|
||||
|
||||
docking_server:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 50.0
|
||||
initial_perception_timeout: 5.0
|
||||
wait_charge_timeout: 5.0
|
||||
dock_approach_timeout: 30.0
|
||||
undock_linear_tolerance: 0.05
|
||||
undock_angular_tolerance: 0.1
|
||||
max_retries: 3
|
||||
base_frame: "base_link"
|
||||
fixed_frame: "odom"
|
||||
dock_backwards: false
|
||||
dock_prestaging_tolerance: 0.5
|
||||
|
||||
# Types of docks
|
||||
dock_plugins: ['simple_charging_dock']
|
||||
simple_charging_dock:
|
||||
plugin: 'opennav_docking::SimpleChargingDock'
|
||||
docking_threshold: 0.05
|
||||
staging_x_offset: -0.7
|
||||
use_external_detection_pose: true
|
||||
use_battery_status: false # true
|
||||
use_stall_detection: false # true
|
||||
|
||||
external_detection_timeout: 1.0
|
||||
external_detection_translation_x: -0.18
|
||||
external_detection_translation_y: 0.0
|
||||
external_detection_rotation_roll: -1.57
|
||||
external_detection_rotation_pitch: -1.57
|
||||
external_detection_rotation_yaw: 0.0
|
||||
filter_coef: 0.1
|
||||
|
||||
# Dock instances
|
||||
# The following example illustrates configuring dock instances.
|
||||
# docks: ['home_dock'] # Input your docks here
|
||||
# home_dock:
|
||||
# type: 'simple_charging_dock'
|
||||
# frame: map
|
||||
# pose: [0.0, 0.0, 0.0]
|
||||
|
||||
controller:
|
||||
k_phi: 3.0
|
||||
k_delta: 2.0
|
||||
v_linear_min: 0.15
|
||||
v_linear_max: 0.15
|
||||
use_collision_detection: true
|
||||
costmap_topic: "local_costmap/costmap_raw"
|
||||
footprint_topic: "local_costmap/published_footprint"
|
||||
transform_tolerance: 0.1
|
||||
projection_time: 5.0
|
||||
simulation_step: 0.1
|
||||
dock_collision_threshold: 0.3
|
||||
|
||||
loopback_simulator:
|
||||
ros__parameters:
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "odom"
|
||||
map_frame_id: "map"
|
||||
scan_frame_id: "base_scan" # tb4_loopback_simulator.launch.py remaps to 'rplidar_link'
|
||||
update_duration: 0.02
|
||||
scan_range_min: 0.05
|
||||
scan_range_max: 30.0
|
||||
scan_angle_min: -3.1415
|
||||
scan_angle_max: 3.1415
|
||||
scan_angle_increment: 0.02617
|
||||
scan_use_inf: true
|
||||
@@ -1,85 +1,44 @@
|
||||
# Modified to use icp_odom frame
|
||||
# Using icp_odom TF instead of odom
|
||||
bt_navigator:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
odom_topic: /odom
|
||||
bt_loop_duration: 10
|
||||
default_server_timeout: 20
|
||||
wait_for_service_timeout: 1000
|
||||
action_server_result_timeout: 900.0
|
||||
navigators: ["navigate_to_pose", "navigate_through_poses"]
|
||||
navigate_to_pose:
|
||||
plugin: "nav2_bt_navigator::NavigateToPoseNavigator"
|
||||
navigate_through_poses:
|
||||
plugin: "nav2_bt_navigator::NavigateThroughPosesNavigator"
|
||||
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
|
||||
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
|
||||
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
|
||||
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
|
||||
plugin_lib_names:
|
||||
- nav2_compute_path_to_pose_action_bt_node
|
||||
- nav2_compute_path_through_poses_action_bt_node
|
||||
- nav2_smooth_path_action_bt_node
|
||||
- nav2_follow_path_action_bt_node
|
||||
- nav2_spin_action_bt_node
|
||||
- nav2_wait_action_bt_node
|
||||
- nav2_assisted_teleop_action_bt_node
|
||||
- nav2_back_up_action_bt_node
|
||||
- nav2_drive_on_heading_bt_node
|
||||
- nav2_clear_costmap_service_bt_node
|
||||
- nav2_is_stuck_condition_bt_node
|
||||
- nav2_goal_reached_condition_bt_node
|
||||
- nav2_goal_updated_condition_bt_node
|
||||
- nav2_globally_updated_goal_condition_bt_node
|
||||
- nav2_is_path_valid_condition_bt_node
|
||||
- nav2_initial_pose_received_condition_bt_node
|
||||
- nav2_reinitialize_global_localization_service_bt_node
|
||||
- nav2_rate_controller_bt_node
|
||||
- nav2_distance_controller_bt_node
|
||||
- nav2_speed_controller_bt_node
|
||||
- nav2_truncate_path_action_bt_node
|
||||
- nav2_truncate_path_local_action_bt_node
|
||||
- nav2_goal_updater_node_bt_node
|
||||
- nav2_recovery_node_bt_node
|
||||
- nav2_pipeline_sequence_bt_node
|
||||
- nav2_round_robin_node_bt_node
|
||||
- nav2_transform_available_condition_bt_node
|
||||
- nav2_time_expired_condition_bt_node
|
||||
- nav2_path_expiring_timer_condition
|
||||
- nav2_distance_traveled_condition_bt_node
|
||||
- nav2_single_trigger_bt_node
|
||||
- nav2_goal_updated_controller_bt_node
|
||||
- nav2_is_battery_low_condition_bt_node
|
||||
- nav2_navigate_through_poses_action_bt_node
|
||||
- nav2_navigate_to_pose_action_bt_node
|
||||
- nav2_remove_passed_goals_action_bt_node
|
||||
- nav2_planner_selector_bt_node
|
||||
- nav2_controller_selector_bt_node
|
||||
- nav2_goal_checker_selector_bt_node
|
||||
- nav2_controller_cancel_bt_node
|
||||
- nav2_path_longer_on_approach_bt_node
|
||||
- nav2_wait_cancel_bt_node
|
||||
- nav2_spin_cancel_bt_node
|
||||
- nav2_back_up_cancel_bt_node
|
||||
- nav2_assisted_teleop_cancel_bt_node
|
||||
- nav2_drive_on_heading_cancel_bt_node
|
||||
- nav2_is_battery_charging_condition_bt_node
|
||||
|
||||
bt_navigator_navigate_through_poses_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
# plugin_lib_names is used to add custom BT plugins to the executor (vector of strings).
|
||||
# Built-in plugins are added automatically
|
||||
# plugin_lib_names: []
|
||||
|
||||
bt_navigator_navigate_to_pose_rclcpp_node:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
error_code_names:
|
||||
- compute_path_error_code
|
||||
- follow_path_error_code
|
||||
|
||||
controller_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 20.0
|
||||
costmap_update_timeout: 0.30
|
||||
min_x_velocity_threshold: 0.001
|
||||
min_y_velocity_threshold: 0.5
|
||||
min_theta_velocity_threshold: 0.001
|
||||
failure_tolerance: 0.3
|
||||
progress_checker_plugin: "progress_checker"
|
||||
progress_checker_plugins: ["progress_checker"]
|
||||
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
|
||||
controller_plugins: ["FollowPath"]
|
||||
use_realtime_priority: false
|
||||
|
||||
# Progress checker parameters
|
||||
progress_checker:
|
||||
@@ -97,48 +56,96 @@ controller_server:
|
||||
plugin: "nav2_controller::SimpleGoalChecker"
|
||||
xy_goal_tolerance: 0.25
|
||||
yaw_goal_tolerance: 0.25
|
||||
# DWB parameters
|
||||
FollowPath:
|
||||
plugin: "dwb_core::DWBLocalPlanner"
|
||||
debug_trajectory_details: True
|
||||
min_vel_x: 0.0
|
||||
min_vel_y: 0.0
|
||||
max_vel_x: 0.26
|
||||
max_vel_y: 0.0
|
||||
max_vel_theta: 1.0
|
||||
min_speed_xy: 0.0
|
||||
max_speed_xy: 0.26
|
||||
min_speed_theta: 0.0
|
||||
# Add high threshold velocity for turtlebot 3 issue.
|
||||
# https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
|
||||
acc_lim_x: 2.5
|
||||
acc_lim_y: 0.0
|
||||
acc_lim_theta: 3.2
|
||||
decel_lim_x: -2.5
|
||||
decel_lim_y: 0.0
|
||||
decel_lim_theta: -3.2
|
||||
vx_samples: 20
|
||||
vy_samples: 5
|
||||
vtheta_samples: 20
|
||||
sim_time: 1.7
|
||||
linear_granularity: 0.05
|
||||
angular_granularity: 0.025
|
||||
transform_tolerance: 0.2
|
||||
xy_goal_tolerance: 0.25
|
||||
trans_stopped_velocity: 0.25
|
||||
short_circuit_trajectory_evaluation: True
|
||||
stateful: True
|
||||
critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
|
||||
BaseObstacle.scale: 0.02
|
||||
PathAlign.scale: 32.0
|
||||
PathAlign.forward_point_distance: 0.1
|
||||
GoalAlign.scale: 24.0
|
||||
GoalAlign.forward_point_distance: 0.1
|
||||
PathDist.scale: 32.0
|
||||
GoalDist.scale: 24.0
|
||||
RotateToGoal.scale: 32.0
|
||||
RotateToGoal.slowing_factor: 5.0
|
||||
RotateToGoal.lookahead_time: -1.0
|
||||
plugin: "nav2_mppi_controller::MPPIController"
|
||||
time_steps: 56
|
||||
model_dt: 0.05
|
||||
batch_size: 2000
|
||||
ax_max: 3.0
|
||||
ax_min: -3.0
|
||||
ay_max: 3.0
|
||||
ay_min: -3.0
|
||||
az_max: 3.5
|
||||
vx_std: 0.2
|
||||
vy_std: 0.2
|
||||
wz_std: 0.4
|
||||
vx_max: 0.5
|
||||
vx_min: -0.35
|
||||
vy_max: 0.5
|
||||
wz_max: 1.9
|
||||
iteration_count: 1
|
||||
prune_distance: 1.7
|
||||
transform_tolerance: 0.1
|
||||
temperature: 0.3
|
||||
gamma: 0.015
|
||||
motion_model: "DiffDrive"
|
||||
visualize: true
|
||||
regenerate_noises: true
|
||||
TrajectoryVisualizer:
|
||||
trajectory_step: 5
|
||||
time_step: 3
|
||||
AckermannConstraints:
|
||||
min_turning_r: 0.2
|
||||
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
|
||||
near_collision_cost: 253
|
||||
critical_cost: 300.0
|
||||
consider_footprint: false
|
||||
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
|
||||
mode: 0
|
||||
# TwirlingCritic:
|
||||
# enabled: true
|
||||
# twirling_cost_power: 1
|
||||
# twirling_cost_weight: 10.0
|
||||
|
||||
local_costmap:
|
||||
local_costmap:
|
||||
@@ -147,7 +154,6 @@ local_costmap:
|
||||
publish_frequency: 2.0
|
||||
global_frame: icp_odom
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
rolling_window: true
|
||||
width: 3
|
||||
height: 3
|
||||
@@ -157,7 +163,7 @@ local_costmap:
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
inflation_radius: 0.70
|
||||
voxel_layer:
|
||||
plugin: "nav2_costmap_2d::VoxelLayer"
|
||||
enabled: True
|
||||
@@ -190,7 +196,6 @@ global_costmap:
|
||||
publish_frequency: 1.0
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
use_sim_time: True
|
||||
robot_radius: 0.22
|
||||
resolution: 0.05
|
||||
track_unknown_space: true
|
||||
@@ -215,23 +220,22 @@ global_costmap:
|
||||
inflation_layer:
|
||||
plugin: "nav2_costmap_2d::InflationLayer"
|
||||
cost_scaling_factor: 3.0
|
||||
inflation_radius: 0.55
|
||||
inflation_radius: 0.7
|
||||
always_send_full_costmap: True
|
||||
|
||||
planner_server:
|
||||
ros__parameters:
|
||||
expected_planner_frequency: 20.0
|
||||
use_sim_time: True
|
||||
planner_plugins: ["GridBased"]
|
||||
costmap_update_timeout: 1.0
|
||||
GridBased:
|
||||
plugin: "nav2_navfn_planner/NavfnPlanner"
|
||||
plugin: "nav2_navfn_planner::NavfnPlanner"
|
||||
tolerance: 0.5
|
||||
use_astar: false
|
||||
allow_unknown: true
|
||||
|
||||
smoother_server:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
smoother_plugins: ["simple_smoother"]
|
||||
simple_smoother:
|
||||
plugin: "nav2_smoother::SimpleSmoother"
|
||||
@@ -241,55 +245,178 @@ smoother_server:
|
||||
|
||||
behavior_server:
|
||||
ros__parameters:
|
||||
costmap_topic: local_costmap/costmap_raw
|
||||
footprint_topic: local_costmap/published_footprint
|
||||
enable_stamped_cmd_vel: True
|
||||
local_costmap_topic: local_costmap/costmap_raw
|
||||
global_costmap_topic: global_costmap/costmap_raw
|
||||
local_footprint_topic: local_costmap/published_footprint
|
||||
global_footprint_topic: global_costmap/published_footprint
|
||||
cycle_frequency: 10.0
|
||||
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
|
||||
spin:
|
||||
plugin: "nav2_behaviors/Spin"
|
||||
plugin: "nav2_behaviors::Spin"
|
||||
backup:
|
||||
plugin: "nav2_behaviors/BackUp"
|
||||
plugin: "nav2_behaviors::BackUp"
|
||||
drive_on_heading:
|
||||
plugin: "nav2_behaviors/DriveOnHeading"
|
||||
plugin: "nav2_behaviors::DriveOnHeading"
|
||||
wait:
|
||||
plugin: "nav2_behaviors/Wait"
|
||||
plugin: "nav2_behaviors::Wait"
|
||||
assisted_teleop:
|
||||
plugin: "nav2_behaviors/AssistedTeleop"
|
||||
global_frame: icp_odom
|
||||
plugin: "nav2_behaviors::AssistedTeleop"
|
||||
local_frame: icp_odom
|
||||
global_frame: map
|
||||
robot_base_frame: base_link
|
||||
transform_tolerance: 0.1
|
||||
use_sim_time: true
|
||||
simulate_ahead_time: 2.0
|
||||
max_rotational_vel: 1.0
|
||||
min_rotational_vel: 0.4
|
||||
rotational_acc_lim: 3.2
|
||||
|
||||
robot_state_publisher:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
|
||||
waypoint_follower:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
loop_rate: 20
|
||||
stop_on_failure: false
|
||||
action_server_result_timeout: 900.0
|
||||
waypoint_task_executor_plugin: "wait_at_waypoint"
|
||||
wait_at_waypoint:
|
||||
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
|
||||
enabled: True
|
||||
waypoint_pause_duration: 200
|
||||
|
||||
route_server:
|
||||
ros__parameters:
|
||||
# The graph_filepath does not need to be specified since it going to be set by defaults in launch.
|
||||
# If you'd rather set it in the yaml, remove the default "graph" value in the launch file(s).
|
||||
# file & provide full path to map below. If graph config or launch default is provided, it is used
|
||||
# graph_filepath: $(find-pkg-share nav2_route)/graphs/aws_graph.geojson
|
||||
boundary_radius_to_achieve_node: 1.0
|
||||
radius_to_achieve_node: 2.0
|
||||
smooth_corners: true
|
||||
operations: ["AdjustSpeedLimit", "ReroutingService", "CollisionMonitor"]
|
||||
ReroutingService:
|
||||
plugin: "nav2_route::ReroutingService"
|
||||
AdjustSpeedLimit:
|
||||
plugin: "nav2_route::AdjustSpeedLimit"
|
||||
CollisionMonitor:
|
||||
plugin: "nav2_route::CollisionMonitor"
|
||||
max_collision_dist: 3.0
|
||||
edge_cost_functions: ["DistanceScorer", "CostmapScorer"]
|
||||
DistanceScorer:
|
||||
plugin: "nav2_route::DistanceScorer"
|
||||
CostmapScorer:
|
||||
plugin: "nav2_route::CostmapScorer"
|
||||
|
||||
velocity_smoother:
|
||||
ros__parameters:
|
||||
use_sim_time: True
|
||||
enable_stamped_cmd_vel: True
|
||||
smoothing_frequency: 20.0
|
||||
stamp_smoothed_velocity_with_smoothing_time: False
|
||||
scale_velocities: False
|
||||
feedback: "OPEN_LOOP"
|
||||
max_velocity: [0.26, 0.0, 1.0]
|
||||
min_velocity: [-0.26, 0.0, -1.0]
|
||||
max_velocity: [0.5, 0.0, 2.0]
|
||||
min_velocity: [-0.5, 0.0, -2.0]
|
||||
max_accel: [2.5, 0.0, 3.2]
|
||||
max_decel: [-2.5, 0.0, -3.2]
|
||||
odom_topic: "odom"
|
||||
odom_duration: 0.1
|
||||
deadband_velocity: [0.0, 0.0, 0.0]
|
||||
velocity_timeout: 1.0
|
||||
|
||||
collision_monitor:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "icp_odom"
|
||||
cmd_vel_in_topic: "cmd_vel_smoothed"
|
||||
cmd_vel_out_topic: "cmd_vel"
|
||||
state_topic: "collision_monitor_state"
|
||||
transform_tolerance: 0.2
|
||||
source_timeout: 1.0
|
||||
base_shift_correction: True
|
||||
stop_pub_timeout: 2.0
|
||||
# Polygons represent zone around the robot for "stop", "slowdown" and "limit" action types,
|
||||
# and robot footprint for "approach" action type.
|
||||
polygons: ["FootprintApproach"]
|
||||
FootprintApproach:
|
||||
type: "polygon"
|
||||
action_type: "approach"
|
||||
footprint_topic: "/local_costmap/published_footprint"
|
||||
time_before_collision: 1.2
|
||||
simulation_time_step: 0.1
|
||||
min_points: 6
|
||||
visualize: False
|
||||
enabled: True
|
||||
observation_sources: ["scan"]
|
||||
scan:
|
||||
type: "scan"
|
||||
topic: "scan"
|
||||
min_height: 0.15
|
||||
max_height: 2.0
|
||||
enabled: True
|
||||
|
||||
docking_server:
|
||||
ros__parameters:
|
||||
enable_stamped_cmd_vel: True
|
||||
controller_frequency: 50.0
|
||||
initial_perception_timeout: 5.0
|
||||
wait_charge_timeout: 5.0
|
||||
dock_approach_timeout: 30.0
|
||||
undock_linear_tolerance: 0.05
|
||||
undock_angular_tolerance: 0.1
|
||||
max_retries: 3
|
||||
base_frame: "base_link"
|
||||
fixed_frame: "icp_odom"
|
||||
dock_backwards: false
|
||||
dock_prestaging_tolerance: 0.5
|
||||
|
||||
# Types of docks
|
||||
dock_plugins: ['simple_charging_dock']
|
||||
simple_charging_dock:
|
||||
plugin: 'opennav_docking::SimpleChargingDock'
|
||||
docking_threshold: 0.05
|
||||
staging_x_offset: -0.7
|
||||
use_external_detection_pose: true
|
||||
use_battery_status: false # true
|
||||
use_stall_detection: false # true
|
||||
|
||||
external_detection_timeout: 1.0
|
||||
external_detection_translation_x: -0.18
|
||||
external_detection_translation_y: 0.0
|
||||
external_detection_rotation_roll: -1.57
|
||||
external_detection_rotation_pitch: -1.57
|
||||
external_detection_rotation_yaw: 0.0
|
||||
filter_coef: 0.1
|
||||
|
||||
# Dock instances
|
||||
# The following example illustrates configuring dock instances.
|
||||
# docks: ['home_dock'] # Input your docks here
|
||||
# home_dock:
|
||||
# type: 'simple_charging_dock'
|
||||
# frame: map
|
||||
# pose: [0.0, 0.0, 0.0]
|
||||
|
||||
controller:
|
||||
k_phi: 3.0
|
||||
k_delta: 2.0
|
||||
v_linear_min: 0.15
|
||||
v_linear_max: 0.15
|
||||
use_collision_detection: true
|
||||
costmap_topic: "local_costmap/costmap_raw"
|
||||
footprint_topic: "local_costmap/published_footprint"
|
||||
transform_tolerance: 0.1
|
||||
projection_time: 5.0
|
||||
simulation_step: 0.1
|
||||
dock_collision_threshold: 0.3
|
||||
|
||||
loopback_simulator:
|
||||
ros__parameters:
|
||||
base_frame_id: "base_footprint"
|
||||
odom_frame_id: "icp_odom"
|
||||
map_frame_id: "map"
|
||||
scan_frame_id: "base_scan" # tb4_loopback_simulator.launch.py remaps to 'rplidar_link'
|
||||
update_duration: 0.02
|
||||
scan_range_min: 0.05
|
||||
scan_range_max: 30.0
|
||||
scan_angle_min: -3.1415
|
||||
scan_angle_max: 3.1415
|
||||
scan_angle_increment: 0.02617
|
||||
scan_use_inf: true
|
||||
|
||||
Reference in New Issue
Block a user