mirror of
https://github.com/6-robot/jie_ware.git
synced 2025-09-15 12:59:05 +08:00
add lidar_filter_node
This commit is contained in:
parent
550dd18382
commit
35e827a6de
@ -227,4 +227,12 @@ add_executable(costmap_cleaner
|
||||
add_dependencies(costmap_cleaner ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
target_link_libraries(costmap_cleaner
|
||||
${catkin_LIBRARIES}
|
||||
)
|
||||
|
||||
add_executable(lidar_filter_node
|
||||
src/lidar_filter_node.cpp
|
||||
)
|
||||
add_dependencies(lidar_filter_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
target_link_libraries(lidar_filter_node
|
||||
${catkin_LIBRARIES}
|
||||
)
|
||||
25
README.md
25
README.md
@ -16,13 +16,18 @@ Youtube: [《代价地图清除》](https://www.youtube.com/watch?v=giHf_PY4EmY)
|
||||
cd ~/catkin_ws/src/
|
||||
git clone https://github.com/6-robot/jie_ware.git
|
||||
```
|
||||
国内镜像:
|
||||
```
|
||||
cd ~/catkin_ws/src/
|
||||
git clone https://gitee.com/s-robot/jie_ware.git
|
||||
```
|
||||
2. 编译
|
||||
```
|
||||
cd ~/catkin_ws
|
||||
catkin_make
|
||||
```
|
||||
## 激光定位
|
||||
1. 修改导航Launch文件,用如下内容替换AMCL节点
|
||||
1. 修改导航Launch文件,用如下内容替换AMCL节点:
|
||||
```
|
||||
<node pkg="jie_ware" type="lidar_loc" name="lidar_loc" >
|
||||
<param name="base_frame" value="base_footprint" />
|
||||
@ -36,8 +41,22 @@ catkin_make
|
||||
roslaunch jie_ware lidar_loc_test.launch
|
||||
```
|
||||
## 代价地图清除
|
||||
1. 修改导航Launch文件,添加如下内容
|
||||
1. 修改导航Launch文件,添加如下内容:
|
||||
```
|
||||
<node pkg="jie_ware" type="costmap_cleaner" name="costmap_cleaner" />
|
||||
```
|
||||
2. 运行修改后的Launch文件,正常设置机器人的估计位置即可。
|
||||
2. 运行修改后的Launch文件,正常设置机器人的估计位置即可。
|
||||
## 激光雷达滤波
|
||||
1. 修改导航Launch文件,添加如下内容:
|
||||
```
|
||||
<node pkg="jie_ware" type="lidar_filter_node" name="lidar_filter_node" />
|
||||
```
|
||||
2. 修改代价地图参数文件 costmap_common_params.yaml ,将激光雷达数据话题 topic 从 scan 修改为 scan_filtered 。
|
||||
```
|
||||
observation_sources: scan
|
||||
|
||||
scan:
|
||||
data_type: LaserScan
|
||||
topic: scan_filtered
|
||||
```
|
||||
3. 运行修改后的Launch文件,正常进行导航。
|
||||
@ -13,7 +13,7 @@
|
||||
<!-- One license tag required, multiple allowed, one license per tag -->
|
||||
<!-- Commonly used license strings: -->
|
||||
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
|
||||
<license>BSD</license>
|
||||
<license>GPL</license>
|
||||
|
||||
|
||||
<!-- Url tags are optional, but mutiple are allowed, one per tag -->
|
||||
|
||||
154
src/lidar_filter_node.cpp
Executable file
154
src/lidar_filter_node.cpp
Executable file
@ -0,0 +1,154 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2020-2025, Waterplus http://www.6-robot.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the WaterPlus nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* FOOTPRINTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
/* @author Zhang Wanjie */
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <sensor_msgs/LaserScan.h>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
class CLidarFilter
|
||||
{
|
||||
public:
|
||||
CLidarFilter(ros::NodeHandle& nh, ros::NodeHandle& pnh);
|
||||
private:
|
||||
ros::NodeHandle n_;
|
||||
ros::Publisher scan_pub_;
|
||||
ros::Subscriber scan_sub_;
|
||||
std::string source_topic_name_;
|
||||
std::string pub_topic_name_;
|
||||
double outlier_threshold_;
|
||||
|
||||
void lidarCallback(const sensor_msgs::LaserScan::ConstPtr& scan);
|
||||
};
|
||||
|
||||
CLidarFilter::CLidarFilter(ros::NodeHandle& nh, ros::NodeHandle& pnh) : n_(nh)
|
||||
{
|
||||
// 从launch文件获取参数
|
||||
pnh.param<std::string>("source_topic", source_topic_name_, "/scan"); // 原始数据话题
|
||||
pnh.param<std::string>("pub_topic", pub_topic_name_, "/scan_filtered"); // 滤波后的数据话题
|
||||
pnh.param<double>("outlier_threshold", outlier_threshold_, 0.1); // 用于离群点判断的阈值
|
||||
|
||||
scan_pub_ = n_.advertise<sensor_msgs::LaserScan>(pub_topic_name_, 10);
|
||||
scan_sub_ = n_.subscribe<sensor_msgs::LaserScan>(source_topic_name_, 10, &CLidarFilter::lidarCallback, this);
|
||||
}
|
||||
|
||||
void CLidarFilter::lidarCallback(const sensor_msgs::LaserScan::ConstPtr& scan)
|
||||
{
|
||||
int nRanges = scan->ranges.size();
|
||||
|
||||
// 如果点数太少,无法进行近邻比较,直接发布原始数据
|
||||
if (nRanges < 3)
|
||||
{
|
||||
scan_pub_.publish(scan);
|
||||
return;
|
||||
}
|
||||
|
||||
sensor_msgs::LaserScan new_scan;
|
||||
|
||||
// 拷贝源数据
|
||||
new_scan.header = scan->header;
|
||||
new_scan.angle_min = scan->angle_min;
|
||||
new_scan.angle_max = scan->angle_max;
|
||||
new_scan.angle_increment = scan->angle_increment;
|
||||
new_scan.time_increment = scan->time_increment;
|
||||
new_scan.scan_time = scan->scan_time;
|
||||
new_scan.range_min = scan->range_min;
|
||||
new_scan.range_max = scan->range_max;
|
||||
new_scan.ranges = scan->ranges;
|
||||
if (!scan->intensities.empty())
|
||||
{
|
||||
new_scan.intensities = scan->intensities;
|
||||
}
|
||||
|
||||
// 对new_scan中的离群点进行剔除
|
||||
// 遍历备份数据 new_scan.ranges,从第二个点到倒数第二个点
|
||||
// 因为第一个点没有前一个点,最后一个点没有后一个点
|
||||
for (int i = 1; i < nRanges - 1; ++i)
|
||||
{
|
||||
float prev_range = new_scan.ranges[i-1];
|
||||
float current_range = new_scan.ranges[i];
|
||||
float next_range = new_scan.ranges[i+1];
|
||||
|
||||
// 检查当前点是否有效 (在min_range和max_range之间,且不是inf/nan)
|
||||
// 使用 new_scan 的 range_min 和 range_max 进行有效性判断
|
||||
bool current_valid = std::isfinite(current_range) &&
|
||||
current_range >= new_scan.range_min &&
|
||||
current_range <= new_scan.range_max;
|
||||
|
||||
if (!current_valid)
|
||||
{
|
||||
continue; // 当前点本身无效,跳过
|
||||
}
|
||||
|
||||
// 检查前后邻居点是否有效
|
||||
bool prev_valid = std::isfinite(prev_range) &&
|
||||
prev_range >= new_scan.range_min &&
|
||||
prev_range <= new_scan.range_max;
|
||||
|
||||
bool next_valid = std::isfinite(next_range) &&
|
||||
next_range >= new_scan.range_min &&
|
||||
next_range <= new_scan.range_max;
|
||||
|
||||
// 只有当当前点和其前后两个邻居点都有效时,才进行离群判断
|
||||
if (prev_valid && next_valid) {
|
||||
if (std::abs(current_range - prev_range) > outlier_threshold_ &&
|
||||
std::abs(current_range - next_range) > outlier_threshold_)
|
||||
{
|
||||
// 判定为离群点,将其无效化
|
||||
new_scan.ranges[i] = std::numeric_limits<float>::infinity();
|
||||
// 如果有强度信息,将其对应强度设为0
|
||||
if (!new_scan.intensities.empty() && i < new_scan.intensities.size())
|
||||
{
|
||||
new_scan.intensities[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scan_pub_.publish(new_scan);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc,argv,"lidar_filter_node");
|
||||
|
||||
ros::NodeHandle nh;
|
||||
ros::NodeHandle pnh("~");
|
||||
|
||||
CLidarFilter lidar_filter(nh, pnh);
|
||||
|
||||
ros::spin();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user