【cartographer_ros】三: 发布和订阅雷达LaserScan信息

本文介绍了如何在ROS系统中处理激光雷达LaserScan数据,包括理解`sensor_msgs/LaserScan`消息结构,编写发布和订阅节点来模拟或处理实际雷达数据,并展示了如何在rviz中查看及通过rosbag订阅数据。此内容对于将雷达数据接入如Cartographer这样的SLAM算法至关重要。

上一节介绍和测试了cartographer的官方demo。

本节会编写ros系统中,最常用的激光雷达LaserScan传感数据的订阅和发布,方便在cartographer中加入自己的数据进行建图与定位。(作者使用的是SICK-NAV350)

官方文档:

http://wiki.ros.org/navigation/Tutorials/RobotSetup/Sensors


目录

1:sensor_msgs/LaserScan消息类型

2:发布LaserScan消息 

3:订阅LaserScan消息


1:sensor_msgs/LaserScan消息类型

在终端查看消息数据结构:

rosmsg show sensor_msgs/LaserScan

LaserScan消息类型数据结构如下:

std_msgs/Header header          
  uint32 seq
  time stamp           
  string frame_id     # in frame frame_id, angles are measured around  the positive Z axis (counterclockwise, if Z is up)
                         # with zero angle being forward along the x axis           
                         
float32 angle_min        # start angle of the scan [rad]
float32 angle_max        # end angle of the scan [rad]
float32 angle_increment  # angular distance between measurements [rad]

float32 time_increment   # time between measurements [seconds] - if your scanner
                         # is moving, this will be used in interpolating position
                         # of 3d points
float32 scan_time        # time between scans [seconds]

float32 range_min        # minimum range value [m]
float32 range_max        # maximum range value [m]

float32[] ranges         # range data [m] (Note: values < range_min or > range_max should be discarded)
float32[] intensities    # intensity data [device-specific units].  If your device does not provide intensities, please leave the array empty.

得到了消息数据结构之后,就可以根据雷达数据填充消息内容。
其中angle_min angle_max angle_increment time_increment range_min range_max等基本上是雷达设置常量。
而ranges表示对应角度的测量距离,intensities表示对应角度的反射强度,这些是动态变化的,需要根据雷达频率更新。


2:发布LaserScan消息 

#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>

int main(int argc, char** argv)
{
    //ros节点初始化
    ros::init(argc, argv, "laser_scan_publisher");
    ros::NodeHandle n;

    //创建LaserScan消息发布Publisher
    ros::Publisher scan_pub = n.advertise<sensor_msgs::LaserScan>("scan", 50);

    //激光雷达参数设置
    unsigned int num_readings = 100;
    double laser_frequency = 40;
    double ranges[num_readings];
    double intensities[num_readings];
    int count = 0;

    ros::Rate r(1.0);

    while(n.ok())
    {
        //为激光扫描生成一些假数据(可替换成自己激光雷达真实数据)
        for(unsigned int i = 0; i < num_readings; ++i)
        {
            ranges[i] = count;
            intensities[i] = 100 + count;
        }
        ros::Time scan_time = ros::Time::now();
    
        //填充 LaserScan 消息
        sensor_msgs::LaserScan scan;
        scan.header.stamp = scan_time;
        scan.header.frame_id = "base_link";
        scan.angle_min = -1.57;
        scan.angle_max = 1.57;
        scan.angle_increment = 3.14 / num_readings;
        scan.time_increment = (1 / laser_frequency) / (num_readings);
        scan.range_min = 0.0;
        scan.range_max = 100.0;
        scan.ranges.resize(num_readings);
        scan.intensities.resize(num_readings);
        for(unsigned int i = 0; i < num_readings; ++i)
        {
            scan.ranges[i] = ranges[i];
            scan.intensities[i] = intensities[i];
        }

        //通过 ROS 发布消息
        scan_pub.publish(scan);

        ++count;
        r.sleep();
    }
}


3:订阅LaserScan消息

通常来说,发布自己激光雷达的信息到ros系统中,同时cartographer节点能够自动订阅接收LaserScan消息,就可以实现将雷达数据传给cartographer算法的目的。
但特定情况下可能需要订阅查看激光雷达的信息。

(1) 通过rosbag订阅

rostopic echo /scan

(2) 通过rviz查看
打开rviz

rosrun rviz rviz

Fixed Frame修改为base_link,添加LaserScan并将Topic设为/scan

 
(3) 编写程序打印

#include "ros/ros.h"
#include "sensor_msgs/LaserScan.h"

void ScanCallback(const sensor_msgs::LaserScan::ConstPtr &msg)
{
    size_t size = msg->ranges.size();
    std::string ranges ="";
    for(size_t i =0; i< size;i++){
        ranges += std::to_string(msg->ranges[i]) + ", ";
    }
    ROS_INFO("Scan: [%s]", ranges);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle node;
    ros::Subscriber subScan = node.subscribe("scan", 1000, ScanCallback);
    ros::spin();
    return 0;
}

【完】


下一节会介绍里程计Odom数据的发布和订阅。

<think>我们已经收集了多个关于cartographer_ros的引用,特别是关于cartographer_node节点信息。用户的问题聚焦于“cartographer_node节点的使用方法”。 根据引用[1][2],我们知道cartographer_roscartographer的上层ROS封装,主要负责订阅传感器数据(如IMU、激光雷达、里程计)并传递给cartographer处理,同时发布处理结果(如地图、轨迹等)以供显示或保存。而cartographer_node是cartographer_ros中的一个核心节点,负责启动SLAM过程。 引用[4]详细说明了cartographer_ros的功能,包括处理传感器数据、定时发布数据、处理ROS服务等,这些功能都与cartographer_node节点密切相关。 因此,我们需要整合这些信息来回答用户的问题。 **回答结构**: 1. 首先解释cartographer_node节点的基本作用。 2. 说明如何启动cartographer_node节点(通常通过启动文件)。 3. 介绍配置方法(参数配置,包括lua文件URDF模型)。 4. 说明如何使用提供的服务(如开始/结束轨迹、保存地图等)。 5. 可能涉及的数据发布订阅。 **具体回答**: </think>### cartographer_node节点的使用方法 `cartographer_node`是cartographer_ros的核心节点,负责SLAM流程的初始化数据调度。其使用包含以下关键步骤: #### 1. **节点启动** 通过ROS启动文件激活节点,通常调用`cartographer_ros`包中的`cartographer_node`可执行文件: ```xml <node name="cartographer_node" pkg="cartographer_ros" type="cartographer_node" args=" -configuration_directory $(find cartographer_ros)/configuration_files -configuration_basename my_robot.lua"> </node> ``` - `-configuration_directory`:指定配置文件目录 - `-configuration_basename`:选择SLAM配置(如`my_robot.lua`)[^1][^2] #### 2. **关键配置** 在`.lua`文件中定义传感器参数与算法行为: ```lua TRAJECTORY_BUILDER = { use_imu_data = true, -- 启用IMU num_laser_scans = 1, -- 激光雷达数量 submaps = { resolution = 0.05, -- 地图分辨率 } } MAP_BUILDER = { pose_graph = { optimize_every_n_nodes = 90 -- 优化频率 } } ``` 需同步配置URDF模型确保传感器坐标系正确[^1][^3]。 #### 3. **数据交互接口** **订阅话题**(输入数据): - 激光数据:`scan` (`sensor_msgs/LaserScan`) - IMU数据:`imu` (`sensor_msgs/Imu`) - 里程计:`odom` (`nav_msgs/Odometry`) [^2][^4] **发布话题**(输出结果): - 子地图:`submap_list` (`cartographer_ros_msgs/SubmapList`) - 轨迹:`trajectory_node_list` (`visualization_msgs/MarkerArray`) - 位姿:`pose` (`geometry_msgs/PoseStamped`) [^4] #### 4. **服务调用** 通过ROS服务控制SLAM流程: ```bash # 开始新轨迹(指定传感器配置) rosservice call /start_trajectory "configuration_directory: '<path>' configuration_basename: 'backpack_2d.lua'" # 结束轨迹并生成地图 rosservice call /finish_trajectory "trajectory_id: 0" # 保存地图到文件 rosservice call /write_state "filename: 'map.pbstream'" ``` 服务列表详见`cartographer_ros_msgs`包[^4]。 #### 5. **调试与可视化** - **RVIZ显示**:加载`cartographer_rviz`插件查看实时地图 - **调试编译**:修改CMakeLists启用Debug模式[^3] - **性能监控**:使用`/read_metrics`服务获取内部状态 > **最佳实践**: > - 启动前确保所有传感器时间同步 > - 2D建图优先验证激光雷达参数,3D建图需配置多传感器融合 > - 轨迹结束后调用`RunFinalOptimization`提升地图质量[^4] ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CloudFlame

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值