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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM