目录
navigation2介绍
navigation2下载安装
参考小鱼的教程
navigation2的general tutorials
这里面介绍了nav2的一些功能的使用
1. 虚拟墙的使用(keepout zone)
1.1 准备mask file
在你原来的地图上加上想要的虚拟墙,并创建对应的yaml文件。
比如在GIMP中,使用黑色涂抹虚拟墙的位置:
涂完之后:
如果导出为pgm,使用ASCII编码
写对应的新建的yaml文件,eg:
image: cartographer_map1_VWall.pgm
mode: trinary
resolution: 0.05
origin: [-15.2, -2.75, 0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.25
只需要将image的名字改为自己的加了虚拟墙的文件名字就行
note:地图三种mode的区别
- trinary:这个就是设置两个阈值,darkness在阈值之上为障碍,之下为坦途,之间为未知区域
- scale:透明度<1为未知,darkness在阈值上为障碍,darkness在阈值下为坦途,中间的就线性插值到最近的整数
- raw:darkness在0为坦途,darkness在100为障碍,中间的意义是-OccupancyGrid = darkness,
1.2 写配置文件
这个文件是给nav2_bringup使用的,其官方默认的配置文件就在navigation2/nav2_bringup/params中,为了不破坏其原来的设置,可以拷贝一份出来。
- 配置 Costmap Filter Info Publisher Server
就是在末尾加入:
costmap_filter_info_server:
ros__parameters:
use_sim_time: true
type: 0
filter_info_topic: "/costmap_filter_info"
mask_topic: "/keepout_filter_mask"
base: 0.0
multiplier: 1.0
filter_mask_server:
ros__parameters:
use_sim_time: true
frame_id: "map"
topic_name: "/keepout_filter_mask"
yaml_filename: "keepout_mask.yaml"
- Enable Keepout Filter
在文件对应的地方加入:
global_costmap:
global_costmap:
ros__parameters:
...
plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
filters: ["keepout_filter"]
...
keepout_filter:
plugin: "nav2_costmap_2d::KeepoutFilter"
enabled: True
filter_info_topic: "/costmap_filter_info"
...
local_costmap:
local_costmap:
ros__parameters:
...
plugins: ["voxel_layer", "inflation_layer"]
filters: ["keepout_filter"]
...
keepout_filter:
plugin: "nav2_costmap_2d::KeepoutFilter"
enabled: True
filter_info_topic: "/costmap_filter_info"
- 如果想要虚拟墙也有膨胀层
global_costmap:
global_costmap:
ros__parameters:
...
plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
filters: ["keepout_filter", "inflation_layer"]
...
keepout_filter:
plugin: "nav2_costmap_2d::KeepoutFilter"
enabled: True
filter_info_topic: "/costmap_filter_info"
...
local_costmap:
local_costmap:
ros__parameters:
...
plugins: ["voxel_layer", "inflation_layer"]
filters: ["keepout_filter", "inflation_layer"]
...
keepout_filter:
plugin: "nav2_costmap_2d::KeepoutFilter"
enabled: True
filter_info_topic: "/costmap_filter_info"
1.3 写launch文件
此文件用于启动filter相关节点
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from nav2_common.launch import RewrittenYaml
def generate_launch_description():
# Get the launch directory
costmap_filters_demo_dir = get_package_share_directory('nav2_costmap_filters_demo')
# Create our own temporary YAML files that include substitutions
lifecycle_nodes = ['filter_mask_server', 'costmap_filter_info_server']
# Parameters
namespace = LaunchConfiguration('namespace')
use_sim_time = LaunchConfiguration('use_sim_time')
autostart = LaunchConfiguration('autostart')
params_file = LaunchConfiguration('params_file')
mask_yaml_file = LaunchConfiguration('mask')
# Declare the launch arguments
declare_namespace_cmd = DeclareLaunchArgument(
'namespace',
default_value='',
description='Top-level namespace')
declare_use_sim_time_cmd = DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation (Gazebo) clock if true')
declare_autostart_cmd = DeclareLaunchArgument(
'autostart', default_value='true',
description='Automatically startup the nav2 stack')
declare_params_file_cmd = DeclareLaunchArgument(
'params_file',
default_value=os.path.join(costmap_filters_demo_dir, 'params', 'keepout_params.yaml'),
description='Full path to the ROS 2 parameters file to use')
declare_mask_yaml_file_cmd = DeclareLaunchArgument(
'mask',
default_value=os.path.join(costmap_filters_demo_dir, 'maps', 'keepout_mask.yaml'),
description='Full path to filter mask yaml file to load')
# Make re-written yaml
param_substitutions = {
'use_sim_time': use_sim_time,
'yaml_filename': mask_yaml_file}
configured_params = RewrittenYaml(
source_file=params_file,
root_key=namespace,
param_rewrites=param_substitutions,
convert_types=True)
# Nodes launching commands
start_lifecycle_manager_cmd = Node(
package='nav2_lifecycle_manager',
executable='lifecycle_manager',
name='lifecycle_manager_costmap_filters',
namespace=namespace,
output='screen',
emulate_tty=True, # https://github.com/ros2/launch/issues/188
parameters=[{'use_sim_time': use_sim_time},
{'autostart': autostart},
{'node_names': lifecycle_nodes}])
start_map_server_cmd = Node(
package='nav2_map_server',
executable='map_server',
name='filter_mask_server',
namespace=namespace,
output='screen',
emulate_tty=True, # https://github.com/ros2/launch/issues/188
parameters=[configured_params])
start_costmap_filter_info_server_cmd = Node(
package='nav2_map_server',
executable='costmap_filter_info_server',
name='costmap_filter_info_server',
namespace=namespace,
output='screen',
emulate_tty=True, # https://github.com/ros2/launch/issues/188
parameters=[configured_params])
ld = LaunchDescription()
ld.add_action(declare_namespace_cmd)
ld.add_action(declare_use_sim_time_cmd)
ld.add_action(declare_autostart_cmd)
ld.add_action(declare_params_file_cmd)
ld.add_action(declare_mask_yaml_file_cmd)
ld.add_action(start_lifecycle_manager_cmd)
ld.add_action(start_map_server_cmd)
ld.add_action(start_costmap_filter_info_server_cmd)
return ld
可以另外启动bringup或者将bringup加入到上述launch中,记得将bringup的配置文件换成新的
nav2_bringup_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource([nav2_bringup_dir,'/launch','/bringup_launch.py']),
launch_arguments={
'map': map_yaml_path,
'use_sim_time': use_sim_time,
'params_file': nav2_param_path}.items(),# 这个就是我们更新的文件地址
)
2. 速度限制区域(speed limit)
就是robot经过对应的区域的时候速度会下降。
2.1 编辑减速区域
同样在GIMP中编辑地图,灰度越高,速度越小。比如70%的灰度,那在里面就只有40%的速度。为了表达每个格子中不同的OccupancyGrid values,地图的mode应该是scale
写对应的yaml
image: turtlebot3_world.pgm
->
image: speed_mask.pgm
mode: trinary
->
mode: scale
occupied_thresh: 0.65
free_thresh: 0.196
->
occupied_thresh: 1.0
free_thresh: 0.0
2.2 配置nav2
在bringup的param配置文件中加入如下的:
- 设置global_costmap:
global_costmap:
global_costmap:
ros__parameters:
...
plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
filters: ["speed_filter"]
...
speed_filter:
plugin: "nav2_costmap_2d::SpeedFilter"
enabled: True
filter_info_topic: "/costmap_filter_info"
speed_limit_topic: "/speed_limit"
- 设置controller_server
controller_server:
ros__parameters:
...
speed_limit_topic: "/speed_limit"
2.3 写launch文件
此launch文件用于开启filter服务
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from nav2_common.launch import RewrittenYaml
def generate_launch_description():
# Get the launch directory
costmap_filters_demo_dir = get_package_share_directory('nav2_costmap_filters_demo')
# Create our own temporary YAML files that include substitutions
lifecycle_nodes = ['filter_mask_server', 'costmap_filter_info_server']
# Parameters
namespace = LaunchConfiguration('namespace')
use_sim_time = LaunchConfiguration('use_sim_time')
autostart = LaunchConfiguration('autostart')
params_file = LaunchConfiguration('params_file')
mask_yaml_file = LaunchConfiguration('mask')
# Declare the launch arguments
declare_namespace_cmd = DeclareLaunchArgument(
'namespace',
default_value='',
description='Top-level namespace')
declare_use_sim_time_cmd = DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation (Gazebo) clock if true')
declare_autostart_cmd = DeclareLaunchArgument(
'autostart', default_value='true',
description='Automatically startup the nav2 stack')
declare_params_file_cmd = DeclareLaunchArgument(
'params_file',
default_value=os.path.join(costmap_filters_demo_dir, 'params', 'speed_params.yaml'),
description='Full path to the ROS 2 parameters file to use')
declare_mask_yaml_file_cmd = DeclareLaunchArgument(
'mask',
default_value=os.path.join(costmap_filters_demo_dir, 'maps', 'speed_mask.yaml'),
description='Full path to filter mask yaml file to load')
# Make re-written yaml
param_substitutions = {
'use_sim_time': use_sim_time,
'yaml_filename': mask_yaml_file}
configured_params = RewrittenYaml(
source_file=params_file,
root_key=namespace,
param_rewrites=param_substitutions,
convert_types=True)
# Nodes launching commands
start_lifecycle_manager_cmd = Node(
package='nav2_lifecycle_manager',
executable='lifecycle_manager',
name='lifecycle_manager_costmap_filters',
namespace=namespace,
output='screen',
emulate_tty=True, # https://github.com/ros2/launch/issues/188
parameters=[{'use_sim_time': use_sim_time},
{'autostart': autostart},
{'node_names': lifecycle_nodes}])
start_map_server_cmd = Node(
package='nav2_map_server',
executable='map_server',
name='filter_mask_server',
namespace=namespace,
output='screen',
emulate_tty=True, # https://github.com/ros2/launch/issues/188
parameters=[configured_params])
start_costmap_filter_info_server_cmd = Node(
package='nav2_map_server',
executable='costmap_filter_info_server',
name='costmap_filter_info_server',
namespace=namespace,
output='screen',
emulate_tty=True, # https://github.com/ros2/launch/issues/188
parameters=[configured_params])
ld = LaunchDescription()
ld.add_action(declare_namespace_cmd)
ld.add_action(declare_use_sim_time_cmd)
ld.add_action(declare_autostart_cmd)
ld.add_action(declare_params_file_cmd)
ld.add_action(declare_mask_yaml_file_cmd)
ld.add_action(start_lifecycle_manager_cmd)
ld.add_action(start_map_server_cmd)
ld.add_action(start_costmap_filter_info_server_cmd)
return ld
同时,这个launch需要一个配置文件,就是上面参数文件:params_file
costmap_filter_info_server:
ros__parameters:
use_sim_time: true
type: 1
filter_info_topic: "/costmap_filter_info"
mask_topic: "/speed_filter_mask"
base: 100.0
multiplier: -1.0
filter_mask_server:
ros__parameters:
use_sim_time: true
frame_id: "map"
topic_name: "/speed_filter_mask"
yaml_filename: "speed_mask.yaml"
3. 碰撞监控(collision monitor)
这个会产生两个box,一个是slowdown box,另一个是stop box,就是说如果有障碍物进入到这两个box之内的话,robot就会减速和停止
这个的使用比较简单,只需要改一些配置就行了。
3.1 设置 Collision Monitor
配置文件在navigation2/nav2_collision_monitor/params中,是给collision_monitor_node.launch.py使用的
collision_monitor:
ros__parameters:
use_sim_time: True
base_frame_id: "base_footprint"
odom_frame_id: "odom"
cmd_vel_in_topic: "cmd_vel_raw"
cmd_vel_out_topic: "cmd_vel"
transform_tolerance: 0.5
source_timeout: 5.0
stop_pub_timeout: 2.0
polygons: ["PolygonStop", "PolygonSlow"]
PolygonStop:
type: "polygon"
points: [0.4, 0.3, 0.4, -0.3, 0.0, -0.3, 0.0, 0.3]
action_type: "stop"
min_points: 4 # max_points: 3 for Humble
visualize: True
polygon_pub_topic: "polygon_stop"
PolygonSlow:
type: "polygon"
points: [0.6, 0.4, 0.6, -0.4, 0.0, -0.4, 0.0, 0.4]
action_type: "slowdown"
min_points: 4 # max_points: 3 for Humble
slowdown_ratio: 0.3
visualize: True
polygon_pub_topic: "polygon_slowdown"
observation_sources: ["scan"]
scan:
type: "scan"
topic: "scan"
其中的point就是规定了各个box的多边形的顶点。
3.2 修改bringup
在navigation2/nav2_bringup/navigation_launch.py
重映射cmd_vel,修改成下面的样子
Node(
package='nav2_controller',
executable='controller_server',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
+ remappings=remappings + [('cmd_vel', 'cmd_vel_raw')]),
...
ComposableNode(
package='nav2_controller',
plugin='nav2_controller::ControllerServer',
name='controller_server',
parameters=[configured_params],
+ remappings=remappings + [('cmd_vel', 'cmd_vel_raw')]),