Cartographer_ros解读

Cartographer_ros主要实现Topics的订阅与发布。订阅是指从IMU,激光雷达,里程计取数据,然后传给Cartographer库。发布是指从Cartographer拿处理的结果,然后发布给ROS,然后可以在rivz上显示。

 1. cartographer_ros/docs/source/ros_api.rst

      此文件描述 了Cartographer_ros订阅与发布了哪些topics及服务。

 2.运行 cartographer_ros

      roslaunch cartographer_ros demo_revo_lds.launch

 3.revo_lds.lua

      此配置文件,描述了发布哪些Topics及名称。在源码中。订阅的Topic在源码中通过ratio of the pulse(脉冲的比率)的方式来定时调用。发布是通过定时器的方式,定时发布。具体值,可以通过此配置文件配置。

       1)定时器方式

      wall_timers_.push_back(node_handle_.createWallTimer(

       ::ros::WallDuration(node_options_.submap_publish_period_sec),

       &Node::PublishSubmapList, this));

       2)ratio方式

      void Node::HandlePointCloud2Message(

       const int trajectory_id, const std::string& sensor_id,

       const sensor_msgs::PointCloud2::ConstPtr& msg) {

       absl::MutexLock lock(&mutex_);

       if (!sensor_samplers_.at(trajectory_id).rangefinder_sampler.Pulse()) {

       return;

       }

       map_builder_bridge_.sensor_bridge(trajectory_id)

       ->HandlePointCloud2Message(sensor_id, msg);

       }

 

 4. cartographer_node

      Cartographer_ros中的一个重要节点

 

 

 

 

1.请先查看:cartographer_ros/docs/source/ros_api.rst 文档

====================

Subscribed Topics:

       scan (`sensor_msgs/LaserScan`_)

       echoes (`sensor_msgs/MultiEchoLaserScan`_)

       points2 (`sensor_msgs/PointCloud2`_)

       imu (`sensor_msgs/Imu`_)

       odom (`nav_msgs/Odometry`_)

 

Published Topics:

       submap_list (`cartographer_ros_msgs/SubmapList`_)

 

Services:

       submap_query (`cartographer_ros_msgs/SubmapQuery`_)

       start_trajectory (`cartographer_ros_msgs/StartTrajectory`_)

       trajectory_query (`cartographer_ros_msgs/TrajectoryQuery`_)

       finish_trajectory (`cartographer_ros_msgs/FinishTrajectory`_)

       write_state (`cartographer_ros_msgs/WriteState`_)

       get_trajectory_states (`cartographer_ros_msgs/GetTrajectoryStates`_)

       read_metrics (`cartographer_ros_msgs/ReadMetrics`_)

====================

2. 运行cartographer_ros

roslaunch cartographer_ros demo_revo_lds.launch

================================

3.revo_lds.lua

       demo_revo_lds.launch 指定加载revo_lds.lua 配置文件。指定topic的名称,发布的Topic的时间间隔。

 

 map_frame = "map",

  tracking_frame = "scan",

  published_frame = "scan",

  odom_frame = "odom",

  provide_odom_frame = false,

  use_odometry = false,

  use_nav_sat = false,

  use_landmarks = false,

  publish_frame_projected_to_2d=false,

  num_laser_scans = 1,

  num_multi_echo_laser_scans = 0,

  num_subdivisions_per_laser_scan = 1,

  num_point_clouds = 0,

  lookup_transform_timeout_sec = 0.2,

  submap_publish_period_sec = 0.3,

  pose_publish_period_sec = 5e-3,

  trajectory_publish_period_sec = 30e-3,

  rangefinder_sampling_ratio = 1.,

  odometry_sampling_ratio = 1.,

  fixed_frame_pose_sampling_ratio = 1.,

  imu_sampling_ratio = 1.,

  landmarks_sampling_ratio = 1.,

===========

map_frame:一般为“map”.用来发布submap的ROS帧ID.

tracking_frame:SLAM算法要跟踪的ROS 帧ID.?

published_frame:用来发布pose的帧ID.?

odom_frame:只要当有里程计信息的时候才会使用。即provide_odom_frame=true.

provide_odom_frame:如果为true,the local, non-loop-closed, continuous pose将会在map_frame 里以odom_frame发布?

publish_frame_projected_to_2d:如果为true,则已经发布的pose将会被完全成2D的pose,没有       roll,pitch或者z-offset?

use_odometry:如果为true,需要提供里程计信息,并话题/odom会订阅nav_msgs/Odometry类型的消       息,在SLAM过程中也会使用这个消息进行建图

use_nav_sat:如果为true,会在话题/fix上订阅sensor_msgs/NavSatFix类型的消息,并且在       globalSLAM中会用到

use_landmarks:如果为true,会在话题/landmarks上订阅cartographer_ros_msgs/LandmarkList类型   的消息,并且在SLAM过程中会用到

 

num_laser_scans:SLAM可以输入的/scan话题数目的最大值

num_muti_echo_laser_scans:SLAM可以输入sensor_msgs/MultiEchoLaserScan话题数目的最大值

num_subdivisions_per_laser_scan:将每个接收到的(multi_echo)激光scan分割成的点云数。 细分 scam可以在扫描仪移动时取消scanner获取的scan。 有一个相应的trajectory builder option可将细分扫描累积到将用于scan_matching的点云中。

num_point_clouds:SLAM可以输入的sensor_msgs/PointCloud2话题数目的最大值

lookup_transform_timeout_sec:使用tf2查找transform的超时时间(秒)。

submap_publish_period_sec:发布submap的时间间隔(秒)

pose_publish_period_sec:发布pose的时间间隔,值为5e-3的时候为200HZ

trajectory_publish_period_sec:发布trajectory markers(trajectory的节点)的时间间隔,值为30e-3    为30ms

 

rangefinder_samping_ratio:测距仪的固定采样ratio

imu_sampling_ratio:IMU message的固定采样ratio

landmarks_sampling_ratio:landmarks message的固定采样ratio,(单位是啥?)

=====================

 

 

4.RVIZ 订阅的topic

    1)TF

    2)/submap_list

   3)/scan_matched_points2

  4)/trajectory_node_list

  5)/landmark_poses_list

  6)/constraint_list

 

5.App

     cartographer_assets_writer

     cartographer_dev_trajectory_comparison

     cartographer_offline_node

     cartographer_rosbag_validate

      cartographer_dev_pbstream_trajectories_to_rosbag

      cartographer_node

       cartographer_pbstream_map_publisher

       cartographer_dev_rosbag_publisher

       cartographer_occupancy_grid_node 

      cartographer_pbstream_to_ros_map

 

 

 

6. Note.cpp  源码分析

 

  0.Node构造函数

 

      1) 定义各种topic

       submap_list_publisher_ =

              node_handle_.advertise<::cartographer_ros_msgs::SubmapList>(

              kSubmapListTopic, kLatestOnlyPublisherQueueSize);

 

       trajectory_node_list_publisher_ =

              node_handle_.advertise<::visualization_msgs::MarkerArray>(

              kTrajectoryNodeListTopic, kLatestOnlyPublisherQueueSize);

 

       landmark_poses_list_publisher_ =

              node_handle_.advertise<::visualization_msgs::MarkerArray>(

              kLandmarkPosesListTopic, kLatestOnlyPublisherQueueSize);

 

       constraint_list_publisher_ =

              node_handle_.advertise<::visualization_msgs::MarkerArray>(

              kConstraintListTopic, kLatestOnlyPublisherQueueSize);

 

       scan_matched_point_cloud_publisher_ =

              node_handle_.advertise<sensor_msgs::PointCloud2>(

              kScanMatchedPointCloudTopic, kLatestOnlyPublisherQueueSize);

      

       2)定义各种服务的发布器。

       service_servers_.push_back(node_handle_.advertiseService(

              kSubmapQueryServiceName, &Node::HandleSubmapQuery, this));

       service_servers_.push_back(node_handle_.advertiseService(

              kTrajectoryQueryServiceName, &Node::HandleTrajectoryQuery, this));

       service_servers_.push_back(node_handle_.advertiseService(

              kStartTrajectoryServiceName, &Node::HandleStartTrajectory, this));

       service_servers_.push_back(node_handle_.advertiseService(

              kFinishTrajectoryServiceName, &Node::HandleFinishTrajectory, this));

       service_servers_.push_back(node_handle_.advertiseService(

              kWriteStateServiceName, &Node::HandleWriteState, this));

       service_servers_.push_back(node_handle_.advertiseService(

              kGetTrajectoryStatesServiceName, &Node::HandleGetTrajectoryStates, this));

       service_servers_.push_back(node_handle_.advertiseService(

              kReadMetricsServiceName, &Node::HandleReadMetrics, this));

 

       3)给各个发布器设置一个时钟,绑定时间到了的处理函数

       wall_timers_.push_back(node_handle_.createWallTimer(

              ::ros::WallDuration(node_options_.submap_publish_period_sec),

              &Node::PublishSubmapList, this));

      

       wall_timers_.push_back(node_handle_.createWallTimer(

              ::ros::WallDuration(node_options_.trajectory_publish_period_sec),

              &Node::PublishTrajectoryNodeList, this));

       ……

 

 

  1.Run

      cartographer_ros/cartographer_ros/cartographer_ros/node_main.cc

      1)创建一个map_builder

       2)创建一个 node

       3)node.StartTrajectoryWithDefaultTopics()->AddTrajectory()

  2.AddTrajectory

       cartographer_ros/cartographer_ros/cartographer_ros/node.cc

       1)map_builder_bridge_.AddTrajectory

              map_builder_->AddTrajectoryBuilder->OnLocalSlamResult

 

       2)AddExtrapolator 插入一个Extrapolator 位姿解析器

 

       3)AddSensorSamplers

              插入一TrajectorySensorSamplers,里面有rangefinder_sampler,odometry_sampler

,fixed_frame_pose_sampler,imu_sampler,landmark_sampler

       4)LaunchSubscribers:订阅相关的topics,并指安处理函数

                      subscribers_[trajectory_id].push_back(

                     {SubscribeWithHandler<sensor_msgs::LaserScan>(

                     &Node::HandleLaserScanMessage, trajectory_id, topic, &node_handle_,

                     this),

                     topic});

 

              subscribers_[trajectory_id].push_back(

                     {SubscribeWithHandler<sensor_msgs::MultiEchoLaserScan>(

                     &Node::HandleMultiEchoLaserScanMessage, trajectory_id, topic,

                     &node_handle_, this),

                     topic});

               如果使用IMU的数据,则:

                        subscribers_[trajectory_id].push_back(

                            {SubscribeWithHandler<sensor_msgs::Imu>(&Node::HandleImuMessage,

                            trajectory_id, kImuTopic,

                            &node_handle_, this),

                  如果使用里程计的数据,则:

                     subscribers_[trajectory_id].push_back(                                                                                            {SubscribeWithHandler<nav_msgs::Odometry>

                             (&Node::HandleOdometryMessage,       trajectory_id, kOdometryTopic,

                              &node_handle_, this),

              如果使用导航,则

                     subscribers_[trajectory_id].push_back(

                            {SubscribeWithHandler<sensor_msgs::NavSatFix>(

                            &Node::HandleNavSatFixMessage, trajectory_id, kNavSatFixTopic,

                            &node_handle_, this)

              如果使用landmaks,则:

                     subscribers_[trajectory_id].push_back(

                            {SubscribeWithHandler<cartographer_ros_msgs::LandmarkList>(

                            &Node::HandleLandmarkMessage, trajectory_id, kLandmarkTopic,

                            &node_handle_, this),

 

 

 

      

 

 

1./submap_list topic的数据

header:

  seq: 272

  stamp:

    secs: 0

    nsecs:         0

  frame_id: "map"

submap:

  -

    trajectory_id: 0

    submap_index: 0

    submap_version: 50

    pose:

      position:

        x: 0.0

        y: 0.0

        z: 0.0

      orientation:

        x: 0.0

        y: 0.0

        z: 0.0

        w: 1.0

    is_frozen: False

2. /constraint_list

  header:

      seq: 0

      stamp:

        secs: 0

        nsecs:         0

      frame_id: "map"

    ns: "Inter constraints, different trajectories"

    id: 4

    type: 5

    action: 0

    pose:

      position:

        x: 0.0

        y: 0.0

        z: 0.1

      orientation:

        x: 0.0

        y: 0.0

        z: 0.0

        w: 1.0

    scale:

      x: 0.025

      y: 0.0

      z: 0.0

    color:

      r: 0.0

      g: 0.0

      b: 0.0

      a: 0.0

    lifetime:

      secs: 0

      nsecs:         0

    frame_locked: False

    points: []

    colors: []

    text: ''

    mesh_resource: ''

    mesh_use_embedded_materials: False

 

3. /trajectory_node_list

    header:

      seq: 0

      stamp:

        secs: 0

        nsecs:         0

      frame_id: "map"

    ns: "Trajectory 0"

    id: 2

    type: 4

    action: 0

    pose:

      position:

        x: 0.0

        y: 0.0

        z: 0.05

      orientation:

        x: 0.0

        y: 0.0

        z: 0.0

        w: 1.0

    scale:

      x: 0.07

      y: 0.0

      z: 0.0

    color:

      r: 0.207129895687

      g: 0.115499980748

      b: 0.769999980927

      a: 0.25

    lifetime:

      secs: 0

      nsecs:         0

    frame_locked: False

    points:

      -

        x: 1.02211357213

        y: 2.15808512043

        z: 0.0

      -

        x: 1.05474171104

        y: 2.13220375749

        z: 0.0

      -

        x: 1.0466034346

        y: 2.12491221525

        z: 0.0

 

    colors: []

    text: ''

    mesh_resource: ''

    mesh_use_embedded_materials: False

 

4./tf

 

transforms:

  -

    header:

      seq: 0

      stamp:

        secs: 1574159625

        nsecs: 351509220

      frame_id: "/base_footprint"

    child_frame_id: "/laser_frame"

    transform:

      translation:

        x: 0.2245

        y: 0.0

        z: 0.2

      rotation:

        x: 0.0

        y: 0.0

        z: 0.0

        w: 1.0

猜你喜欢

转载自www.cnblogs.com/colinqin/p/cartographer_ros.html