You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ROS激光PCA车道检测节点:无效Publisher调用错误求助

车道检测ROS节点Marker发布报错问题解决

问题描述

基于PCA算法实现激光扫描数据车道检测的ROS节点,代码可通过catkin_make编译,但运行时出现Marker发布失败的致命错误,提示调用了无效的Publisher。

错误信息

[FATAL] [1682304485.986580762]: ASSERTION FAILED
    file = /opt/ros/noetic/include/ros/publisher.h
    line = 107
    cond = false
    message = 
[FATAL] [1682304485.989028993]: Call to publish() on an invalid Publisher
[FATAL] [1682304485.989061888]: 

节点代码

#include <iostream>
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <vector> 
#include <sensor_msgs/LaserScan.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <laser_geometry/laser_geometry.h>
#include <tf/transform_listener.h>
#include <Eigen/Core>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl_conversions/pcl_conversions.h>
#include "ros/ros.h"
#include <pcl/common/pca.h>
#include <pcl/io/io.h>
#include <pcl/conversions.h> 
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <visualization_msgs/MarkerArray.h>
#include <pcl/io/pcd_io.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>

//using namespace std;
laser_geometry::LaserProjection projector_;
ros::Publisher pub_marker;

void getOrientation (const sensor_msgs::LaserScan::ConstPtr& scan)

{
    //convert laser scan into point clouds
    sensor_msgs::PointCloud2 cloud;
    projector_.projectLaser(*scan, cloud);

    //Construct a buffer used by the pca analysis
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud< pcl::PointXYZ>);   
    pcl::fromROSMsg (cloud, *cloud1);
    pcl::PCA<pcl::PointXYZ> pca;
    //pcl::PCA<PointT> pca;

    pca.setInputCloud(cloud1);
    Eigen::Vector3f eigen_values;
    eigen_values=pca.getEigenValues();
    Eigen::Matrix3f eigen_vector;
    eigen_vector=pca.getEigenVectors();

        /* 4. PCA Visualization */
    visualization_msgs::Marker points;
    points.header = cloud.header;
    points.header.frame_id = "/laser_frame"; // odom -> /base_link
    //points.header.frame_id = header.frame_id;
    points.header.stamp = cloud.header.stamp; // ros::Time::now() -> header.stamp
    
    points.ns = "pca"; // namespace + id
    points.id = 0; // pca/0
    points.action = visualization_msgs::Marker::ADD;
    points.type = visualization_msgs::Marker::ARROW;

    points.pose.orientation.w = 1.0;
    points.scale.x = 0.05;
    points.scale.y = 0.05;
    points.scale.z = 0.05;
    points.color.g = 1.0f;
    points.color.r = 0.0f;
    points.color.b = 0.0f;
    points.color.a = 1.0;

    geometry_msgs::Point p_0, p_1;
    p_0.x = 0; p_0.y = 0; p_0.z = 0; // get from tf
    p_1.x = eigen_vector(0,0);
    p_1.y = eigen_vector(0,1); // always negative
    std::cerr << "y = " << eigen_vector(0,1) << std::endl;
    //p_1.z = eigen_vector(0,2);
    points.points.push_back(p_0);
    points.points.push_back(p_1);
    pub_marker.publish(points);

}
 int main(int argc, char **argv)
 {
    
    // Initiate a new ROS node named "talker"
    ros::init(argc, argv, "lane_detection_pca_node");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/scan", 100, getOrientation);
    ros::Publisher pub_marker = nh.advertise<visualization_msgs::Marker>("points", 100);
    ros::spin();
    return 0;
}

问题原因与解决方案

问题原因

代码中声明了全局的ros::Publisher pub_marker,但在main函数里又重新声明了一个同名的局部ros::Publisher pub_marker,局部变量覆盖了全局变量,导致全局的pub_marker从未被初始化(始终是无效状态),当回调函数getOrientation中调用pub_marker.publish(points)时就会触发报错。

解决方案

修改main函数中的Publisher初始化代码,去掉局部变量的声明,直接给全局pub_marker赋值:

修改后的main函数片段:

int main(int argc, char **argv)
{
    ros::init(argc, argv, "lane_detection_pca_node");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/scan", 100, getOrientation);
    // 去掉局部变量声明,直接赋值给全局pub_marker
    pub_marker = nh.advertise<visualization_msgs::Marker>("points", 100);
    ros::spin();
    return 0;
}

这样全局的pub_marker会被正确初始化为有效的Publisher,回调函数中就能正常发布Marker消息了。

内容的提问来源于stack exchange,提问作者Bob9710

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:34:54