遇到采集的地图范围较大时,生成的点云地图也会比较大,例如我采集建图并进行0.1降采样的数据,PCD点云大约900M,这么大的点云points_map_loader是无法一次性加载并pub到topic的,必须进行点云分割和动态分块加载。本文就带大家一起尝试下解决方法。
一、切割PCD
大概思路就是根据GridSzie或者AreaSize自动分配好切割网格的数量和尺寸,然后把pcd points根据xy坐标分别放入对应的pcd文件即可,具体代码可以到github里看,这里不再赘述。
# 编译
git clone https://github.com/yanjingang/SmartCar-pcd-map-Tools
catkin_make -DCATKIN_WHITELIST_PACKAGES=grid_map_generator
source devel/setup.bash
# 切割PCD(点云文件命名:{grid_size}_{min_x}_{min_y}.pcd 例如30_-60_90.pcd表示该点云区域范围为[-60:-30, 90:120])
roscd grid_map_generator
./script/grid_map_generator.sh start # this will start 3 process, roscore/rviz and traj_generator
./scripts/grid_map_generator.sh stop
二、MapLoader动态加载
我们需要对points_map_loader模块进行改造,根据车辆当前位置,实时加载当前区域地图,供NDT_Matching更新target_map。
/points_map的发布订阅关系:
points_map_loader修改points_area为非noupdate,points_area_list传入上一步生成的arealist.csv,以触发area list加载逻辑:初始化时读取points_area_list里的pcd文件列表和min/max xy值,然后根据当前pose+margin动态加载对应的pcd文件并pub到topic(尽量控制pub频次,避免网络带宽、内存等资源占用)
vim Autoware/src/autolaunch/launch/localization.launch
<arg name="points_map" default="$(arg map_path)/$(arg map_name)/points-map/grid-area/"/> <!-- pointcloud .pcd file or .pcd path -->
<arg name="points_area" default="9x9" /> <!-- noupdate or 9x9 -->
<arg name="points_area_list" default="$(arg map_path)/$(arg map_name)/points-map/grid-area/arealist.csv" /> <!-- arealist.csv file path -->
<node pkg="map_file" type="points_map_loader" name="points_map_loader" >
<rosparam subst_value="true">
area: $(arg points_area)
arealist_path: $(arg points_area_list)
pcd_paths: [ $(arg points_map) ]
update_rate: 30000
</rosparam>
</node>
vim Autoware/src/autoware/common/map_file/nodes/points_map_loader/points_map_loader.cpp
// 关联加载附近地图的距离
constexpr double MARGIN_UNIT = 20; //100; // meter
constexpr int ROUNDING_UNIT = 200; //1000; // meter
// 3个触发动态加载point对应area pcd的topic,
gnss_sub = nh.subscribe("gnss_pose", 1000, publish_gnss_pcd);
current_sub = nh.subscribe("current_pose", 1000, publish_current_pcd);
initial_sub = nh.subscribe("initialpose", 1, publish_dragged_pcd);
// 注意用update_rate拦截下,否则会频繁pub地图,比较占用资源
void publish_dragged_pcd(const geometry_msgs::PoseWithCovarianceStamped& msg)
{
ros::Time now = ros::Time::now();
if (((now - current_time).toSec() * 1000) < update_rate)
return;
...
}
// arealist.csv里没有路径,这里用pcd_paths拼接下
//AreaList areas = read_arealist(arealist_path);
AreaList areas = read_arealist(arealist_path, pcd_paths[0]);
*注:
- 新地图,先用gnss:=0调试好geo_pos_conv.cpp的T偏移,再打开gnss:=1调试定位,都ready后再来调试动态加载,否则频繁的initialpose也会导致频繁的加载。
- 不要打开donwload地图,只用本地的arealist.csv+pcds文件即可。
参考: