上传文件至 src/rc_lidar
This commit is contained in:
parent
2f3e6caa8d
commit
a6209c06f0
63
src/rc_lidar/caijian.py
Normal file
63
src/rc_lidar/caijian.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import rclpy
|
||||||
|
from rclpy.node import Node
|
||||||
|
from sensor_msgs.msg import PointCloud2, PointField
|
||||||
|
import numpy as np
|
||||||
|
import struct
|
||||||
|
from sklearn.cluster import DBSCAN
|
||||||
|
|
||||||
|
class LidarFilterNode(Node):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__('caijian_node')
|
||||||
|
self.publisher_ = self.create_publisher(PointCloud2, '/livox/lidar_filtered', 10)
|
||||||
|
self.subscription = self.create_subscription(
|
||||||
|
PointCloud2,
|
||||||
|
'/livox/lidar/pointcloud',
|
||||||
|
self.filter_callback,
|
||||||
|
10)
|
||||||
|
self.get_logger().info('caijian_node started, numpy filtering z in [1.5,3]m, distance<=12m, remove isolated points')
|
||||||
|
|
||||||
|
def filter_callback(self, msg):
|
||||||
|
num_points = msg.width * msg.height
|
||||||
|
data = np.frombuffer(msg.data, dtype=np.uint8)
|
||||||
|
points = np.zeros((num_points, 4), dtype=np.float32) # x, y, z, intensity
|
||||||
|
|
||||||
|
for i in range(num_points):
|
||||||
|
offset = i * msg.point_step
|
||||||
|
x = struct.unpack_from('f', data, offset)[0]
|
||||||
|
y = struct.unpack_from('f', data, offset + 4)[0]
|
||||||
|
z = struct.unpack_from('f', data, offset + 8)[0]
|
||||||
|
intensity = struct.unpack_from('f', data, offset + 12)[0]
|
||||||
|
points[i] = [x, y, z, intensity]
|
||||||
|
|
||||||
|
z_mask = (points[:,2] >= 1.5) & (points[:,2] <= 3.0)
|
||||||
|
dist_mask = np.linalg.norm(points[:,:3], axis=1) <= 16.0
|
||||||
|
mask = z_mask & dist_mask
|
||||||
|
filtered_points = points[mask]
|
||||||
|
|
||||||
|
# 使用DBSCAN去除孤立点
|
||||||
|
if filtered_points.shape[0] > 0:
|
||||||
|
clustering = DBSCAN(eps=0.3, min_samples=5).fit(filtered_points[:,:3])
|
||||||
|
core_mask = clustering.labels_ != -1
|
||||||
|
filtered_points = filtered_points[core_mask]
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
PointField(name='x', offset=0, datatype=PointField.FLOAT32, count=1),
|
||||||
|
PointField(name='y', offset=4, datatype=PointField.FLOAT32, count=1),
|
||||||
|
PointField(name='z', offset=8, datatype=PointField.FLOAT32, count=1),
|
||||||
|
PointField(name='intensity', offset=12, datatype=PointField.FLOAT32, count=1),
|
||||||
|
]
|
||||||
|
filtered_points_list = filtered_points.tolist()
|
||||||
|
import sensor_msgs_py.point_cloud2 as pc2
|
||||||
|
filtered_msg = pc2.create_cloud(msg.header, fields, filtered_points_list)
|
||||||
|
self.publisher_.publish(filtered_msg)
|
||||||
|
|
||||||
|
def main(args=None):
|
||||||
|
rclpy.init(args=args)
|
||||||
|
node = LidarFilterNode()
|
||||||
|
rclpy.spin(node)
|
||||||
|
node.destroy_node()
|
||||||
|
rclpy.shutdown()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue
Block a user