当前位置:   article > 正文

ros2 -foxy安装cartographer建图定位-- 源码安装 使用

foxy安装cartographer

foxy 的cartographer_ros 和dashing 的兼容

cd  ~/xx__ws/src

安装源码

git clone https://ghproxy.com/https://github.com/ros2/cartographer.git -b foxy

git clone https://ghproxy.com/https://github.com/ros2/cartographer_ros.git -b dashing

安装依赖

sudo apt update
sudo apt install -y \
    clang \
    cmake \
    g++ \
    git \
    google-mock \
    libceres-dev \
    liblua5.3-dev \
    libboost-all-dev \
    libprotobuf-dev \
    protobuf-compiler \
    libeigen3-dev \
    libgflags-dev \
    libgoogle-glog-dev \
    libcairo2-dev \
    libpcl-dev \
    libsuitesparse-dev \
    python3-sphinx \
    lsb-release \
    ninja-build \
    stow
 

lua文件:

  1. include "map_builder.lua"
  2. include "trajectory_builder.lua"
  3. options = {
  4. map_builder = MAP_BUILDER,
  5. trajectory_builder = TRAJECTORY_BUILDER,
  6. map_frame = "map",
  7. tracking_frame = "gyro_link",
  8. published_frame = "base_footprint",
  9. odom_frame = "odom",
  10. provide_odom_frame = true,
  11. publish_frame_projected_to_2d = false,
  12. -- publish_tracked_pose=true, --发布小车位置
  13. use_odometry = true,
  14. use_nav_sat = false,
  15. use_landmarks = false,
  16. num_laser_scans = 1,
  17. num_multi_echo_laser_scans = 0,
  18. num_subdivisions_per_laser_scan = 1,
  19. num_point_clouds = 0,
  20. lookup_transform_timeout_sec = 0.2,
  21. submap_publish_period_sec = 0.3,
  22. pose_publish_period_sec = 5e-3,
  23. trajectory_publish_period_sec = 30e-3,
  24. rangefinder_sampling_ratio = 1.,
  25. odometry_sampling_ratio = 1.,
  26. fixed_frame_pose_sampling_ratio = 1.,
  27. imu_sampling_ratio = 1.,
  28. landmarks_sampling_ratio = 1.,
  29. }
  30. MAP_BUILDER.use_trajectory_builder_2d = true
  31. MAP_BUILDER.num_background_threads = 2
  32. -- TRAJECTORY_BUILDER.pure_localization_trimmer.max_submaps_to_keep = 3
  33. TRAJECTORY_BUILDER_2D.submaps.num_range_data = 45
  34. TRAJECTORY_BUILDER_2D.min_range = 0.1
  35. TRAJECTORY_BUILDER_2D.max_range = 6.
  36. TRAJECTORY_BUILDER_2D.missing_data_ray_length = 1.
  37. TRAJECTORY_BUILDER_2D.use_imu_data = true --是否使用imu数据
  38. TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true
  39. -- TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1
  40. -- TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.angular_search_window = math.rad(10.) --角度搜索框的大小
  41. -- TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 10.
  42. -- TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1
  43. TRAJECTORY_BUILDER_2D.motion_filter.max_distance_meters = 0.05 --运动滤波更新距离 // 如果移动距离过小, 或者时间过短, 不进行地图的更新
  44. TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.03)
  45. TRAJECTORY_BUILDER_2D.motion_filter.max_time_seconds = 0.5
  46. TRAJECTORY_BUILDER_2D.ceres_scan_matcher.ceres_solver_options.num_threads = 1
  47. TRAJECTORY_BUILDER_2D.ceres_scan_matcher.ceres_solver_options.max_num_iterations = 20 --迭代次数
  48. POSE_GRAPH.optimization_problem.huber_scale = 1e2
  49. POSE_GRAPH.constraint_builder.max_constraint_distance = 15.
  50. POSE_GRAPH.constraint_builder.sampling_ratio = 0.03
  51. POSE_GRAPH.constraint_builder.min_score = 0.50
  52. POSE_GRAPH.constraint_builder.global_localization_min_score = 0.60
  53. POSE_GRAPH.optimize_every_n_nodes = 35
  54. return options

建图launch:

  1. import os
  2. from launch import LaunchDescription
  3. from launch.substitutions import LaunchConfiguration
  4. from launch_ros.actions import Node
  5. from launch_ros.substitutions import FindPackageShare
  6. from ament_index_python.packages import get_package_share_directory
  7. from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription
  8. from launch.conditions import IfCondition
  9. from launch.launch_description_sources import PythonLaunchDescriptionSource
  10. def generate_launch_description():
  11. # 定位到功能包的地址
  12. pkg_share = FindPackageShare(package='carerobot_pkg').find('carerobot_pkg')
  13. scan_dir = get_package_share_directory('rplidar_ros')
  14. scan_launch_dir = os.path.join(scan_dir, 'launch') #雷达launch文件路径
  15. serial_dir = get_package_share_directory('serial_pkg')
  16. serial_launch_dir = os.path.join(serial_dir, 'launch') #串口launch文件路径
  17. remappings = [('/tf', 'tf'),
  18. ('/tf_static', 'tf_static')]
  19. urdf = os.path.join(pkg_share, 'urdf', 'careRobot.urdf') #模型
  20. #=====================运行节点需要的配置=======================================================================
  21. # 是否使用仿真时间,我们用gazebo,这里设置成true
  22. use_sim_time = LaunchConfiguration('use_sim_time', default='false')
  23. # 地图的分辨率
  24. resolution = LaunchConfiguration('resolution', default='0.01')
  25. # 地图的发布周期
  26. publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0')
  27. # 配置文件夹路径
  28. configuration_directory = LaunchConfiguration('configuration_directory',default= os.path.join(pkg_share, 'config') )
  29. # 配置文件
  30. configuration_basename = LaunchConfiguration('configuration_basename', default='careRobot_2d.lua')
  31. start_robot_state_publisher_cmd = Node( #发布小车TF信息
  32. package='robot_state_publisher',
  33. executable='robot_state_publisher',
  34. remappings=remappings,
  35. arguments=[urdf])
  36. joint_state_publisher_node = Node(
  37. package='joint_state_publisher',
  38. executable='joint_state_publisher',
  39. remappings=remappings,
  40. arguments=[urdf]
  41. )
  42. serial_cmd = IncludeLaunchDescription( #串口开启
  43. PythonLaunchDescriptionSource(os.path.join(serial_launch_dir, 'serial_pkg.launch.py')),
  44. launch_arguments={'namespace': '',
  45. 'use_namespace': 'False'}.items())
  46. scan_cmd = IncludeLaunchDescription( #雷达开启
  47. PythonLaunchDescriptionSource(os.path.join(scan_launch_dir, 'rplidar_A1.launch.py')),
  48. launch_arguments={'namespace': '',
  49. 'use_namespace': 'False'}.items())
  50. #=====================声明三个节点,cartographer/occupancy_grid_node/rviz_node=================================
  51. cartographer_node = Node(
  52. package='cartographer_ros',
  53. executable='cartographer_node',
  54. name='cartographer_node',
  55. output='screen',
  56. parameters=[{'use_sim_time': use_sim_time}],
  57. arguments=['-configuration_directory', configuration_directory,
  58. '-configuration_basename', configuration_basename])
  59. occupancy_grid_node = Node(
  60. package='cartographer_ros',
  61. executable='occupancy_grid_node',
  62. name='occupancy_grid_node',
  63. output='screen',
  64. parameters=[{'use_sim_time': use_sim_time}],
  65. arguments=['-resolution', resolution, '-publish_period_sec', publish_period_sec])
  66. rviz_node = Node(
  67. package='rviz2',
  68. executable='rviz2',
  69. name='rviz2',
  70. # arguments=['-d', rviz_config_dir],
  71. parameters=[{'use_sim_time': use_sim_time}],
  72. output='screen')
  73. #===============================================定义启动文件========================================================
  74. ld = LaunchDescription()
  75. ld.add_action(serial_cmd)
  76. ld.add_action(scan_cmd)
  77. # Add the actions to launch all of the navigation nodes
  78. ld.add_action(start_robot_state_publisher_cmd)
  79. ld.add_action(joint_state_publisher_node)
  80. ld.add_action(cartographer_node)
  81. ld.add_action(occupancy_grid_node)
  82. # ld.add_action(rviz_node) 在虚拟机上面远程启动
  83. return ld

地图保存1:ros2 run nav2_map_server map_saver_cli -t map -f   name    //只是文件名  xx.yaml xx.pgm

地图保存2:


ros2 service call /write_state cartographer_ros_msgs/srv/WriteState "{filename: 'path/cartorapher.pbstream'}"  //绝对路径

ros2 service call /finish_trajectory cartographer_ros_msgs/srv/FinishTrajectory "{trajectory_id: '0'}"  //结束轨迹

定位launch:

  1. import os
  2. from launch import LaunchDescription
  3. from launch.substitutions import LaunchConfiguration
  4. from launch_ros.actions import Node
  5. from launch_ros.substitutions import FindPackageShare
  6. from ament_index_python.packages import get_package_share_directory
  7. from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription
  8. from launch.conditions import IfCondition
  9. from launch.launch_description_sources import PythonLaunchDescriptionSource
  10. from nav2_common.launch import RewrittenYaml
  11. #定位 launch
  12. def generate_launch_description():
  13. # 定位到功能包的地址
  14. pkg_share = FindPackageShare(package='carerobot_pkg').find('carerobot_pkg')
  15. scan_dir = get_package_share_directory('rplidar_ros')
  16. scan_launch_dir = os.path.join(scan_dir, 'launch') #雷达launch文件路径
  17. serial_dir = get_package_share_directory('serial_pkg')
  18. serial_launch_dir = os.path.join(serial_dir, 'launch') #串口launch文件路径
  19. remappings = [('/tf', 'tf'),
  20. ('/tf_static', 'tf_static')]
  21. urdf = os.path.join(pkg_share, 'urdf', 'careRobot.urdf') #模型
  22. #=====================运行节点需要的配置=======================================================================
  23. # 是否使用仿真时间,我们用gazebo,这里设置成true
  24. use_sim_time = LaunchConfiguration('use_sim_time', default='false')
  25. # 地图的分辨率
  26. resolution = LaunchConfiguration('resolution', default='0.01')
  27. # 地图的发布周期
  28. publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0')
  29. # 配置文件夹路径
  30. configuration_directory = LaunchConfiguration('configuration_directory',default= os.path.join(pkg_share, 'config') )
  31. # 配置文件
  32. configuration_basename = LaunchConfiguration('configuration_basename', default='careRobot_2d.lua')
  33. autostart = LaunchConfiguration('autostart', default='True')
  34. #配置地图
  35. configuration_map = LaunchConfiguration('configuration_map', default=os.path.join(pkg_share, 'maps', 'careRobot.pbstream'))
  36. map_yaml_file = LaunchConfiguration('configuration_map', default=os.path.join(pkg_share, 'maps', 'careRobot.yaml'))
  37. #配置导航文件
  38. configuration_nav_params = LaunchConfiguration('configuration_nav_params', default=os.path.join(pkg_share, 'params', 'careRobot_nav.yaml'))
  39. default_bt_xml_filename = LaunchConfiguration('default_bt_xml_filename',
  40. default=os.path.join(get_package_share_directory('nav2_bt_navigator'),
  41. 'behavior_trees', 'navigate_w_replanning_and_recovery.xml'))
  42. map_subscribe_transient_local = LaunchConfiguration('map_subscribe_transient_local', default='True')
  43. namespace = LaunchConfiguration('namespace', default='')
  44. lifecycle_nodes = ['controller_server',
  45. 'planner_server',
  46. 'recoveries_server',
  47. 'bt_navigator',
  48. 'waypoint_follower']
  49. serial_cmd = IncludeLaunchDescription( #串口开启
  50. PythonLaunchDescriptionSource(os.path.join(serial_launch_dir, 'serial_pkg.launch.py')),
  51. launch_arguments={'namespace': '',
  52. 'use_namespace': 'False'}.items())
  53. scan_cmd = IncludeLaunchDescription( #雷达开启
  54. PythonLaunchDescriptionSource(os.path.join(scan_launch_dir, 'rplidar_A1.launch.py')),
  55. launch_arguments={'namespace': '',
  56. 'use_namespace': 'False'}.items())
  57. #=====================声明三个节点,cartographer/occupancy_grid_node/rviz_node=================================
  58. start_robot_state_publisher_cmd = Node( #发布小车TF信息
  59. package='robot_state_publisher',
  60. executable='robot_state_publisher',
  61. remappings=remappings,
  62. arguments=[urdf])
  63. joint_state_publisher_node = Node(
  64. package='joint_state_publisher',
  65. executable='joint_state_publisher',
  66. remappings=remappings,
  67. arguments=[urdf]
  68. )
  69. cartographer_node = Node(
  70. package = 'cartographer_ros',
  71. executable = 'cartographer_node',
  72. name='cartographer_node',
  73. parameters = [{'use_sim_time': True}],
  74. arguments = [
  75. '-configuration_directory',configuration_directory, #配置文件路径
  76. '-configuration_basename', configuration_basename, #配置文件名
  77. '-load_state_filename', configuration_map #pbstream地图
  78. ],
  79. # remappings = [
  80. # ('echoes', 'horizontal_laser_2d')],
  81. output = 'screen'
  82. )
  83. occupancy_grid_node = Node(
  84. package='cartographer_ros',
  85. executable='occupancy_grid_node',
  86. name='occupancy_grid_node',
  87. output='screen',
  88. parameters=[{'use_sim_time': use_sim_time}],
  89. arguments=['-resolution', resolution, '-publish_period_sec', publish_period_sec])
  90. rviz_node = Node(
  91. package='rviz2',
  92. executable='rviz2',
  93. name='rviz2',
  94. # arguments=['-d', rviz_config_dir],
  95. parameters=[{'use_sim_time': use_sim_time}],
  96. output='screen')
  97. param_substitutions = {
  98. 'use_sim_time': use_sim_time,
  99. 'default_bt_xml_filename': default_bt_xml_filename,
  100. 'autostart': autostart,
  101. 'map_subscribe_transient_local': map_subscribe_transient_local}
  102. configured_params = RewrittenYaml(
  103. source_file=configuration_nav_params,
  104. root_key=namespace,
  105. param_rewrites=param_substitutions,
  106. convert_types=True)
  107. nav2_controller_node= Node( #导航控制器
  108. package='nav2_controller',
  109. executable='controller_server',
  110. output='screen',
  111. parameters=[configured_params],
  112. remappings=remappings)
  113. nav2_planner_node=Node( #导航归化器
  114. package='nav2_planner',
  115. executable='planner_server',
  116. name='planner_server',
  117. output='screen',
  118. parameters=[configured_params],
  119. remappings=remappings)
  120. nav2_recoveries_node=Node( #导航恢复
  121. package='nav2_recoveries',
  122. executable='recoveries_server',
  123. name='recoveries_server',
  124. output='screen',
  125. parameters=[configured_params],
  126. remappings=remappings)
  127. nav2_bt_navigator_node=Node( #行为树
  128. package='nav2_bt_navigator',
  129. executable='bt_navigator',
  130. name='bt_navigator',
  131. output='screen',
  132. parameters=[configured_params],
  133. remappings=remappings)
  134. nav2_waypoint_follower_node=Node(#点跟随
  135. package='nav2_waypoint_follower',
  136. executable='waypoint_follower',
  137. name='waypoint_follower',
  138. output='screen',
  139. parameters=[configured_params],
  140. remappings=remappings)
  141. nav2_lifecycle_manager_node=Node( #生命周期
  142. package='nav2_lifecycle_manager',
  143. executable='lifecycle_manager',
  144. name='lifecycle_manager_navigation',
  145. output='screen',
  146. parameters=[{'use_sim_time': use_sim_time},
  147. {'autostart': autostart},
  148. {'node_names': lifecycle_nodes}])
  149. #===============================================定义启动文件========================================================
  150. ld = LaunchDescription()
  151. ld.add_action(serial_cmd)
  152. ld.add_action(scan_cmd)
  153. # Add the actions to launch all of the navigation nodes
  154. ld.add_action(start_robot_state_publisher_cmd)
  155. ld.add_action(joint_state_publisher_node)
  156. ld.add_action(cartographer_node)
  157. ld.add_action(occupancy_grid_node)
  158. ld.add_action(nav2_controller_node)
  159. ld.add_action(nav2_planner_node)
  160. ld.add_action(nav2_recoveries_node)
  161. ld.add_action(nav2_bt_navigator_node)
  162. ld.add_action(nav2_waypoint_follower_node)
  163. ld.add_action(nav2_lifecycle_manager_node)
  164. #ld.add_action(rviz_node)
  165. return ld

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/876938
推荐阅读
相关标签
  

闽ICP备14008679号