@iStarLee
2019-07-10T15:57:26.000000Z
字数 3675
阅读 721
SLAM-LaserSLAM
Author | Wenqiang Chen, Pengpeng Su, Silin Li |
---|---|
Data | 07/01/2019 |
上图是去除地面点的原理示意图,如果上下两线之间点的XYZ坐标差构成的的俯仰角小于一定的阈值,程序中设置的是10°,那么可以认为是地面点。
核心代码如下
// 如果俯仰角在10度以内,则判定(i,j)为地面点,groundMat[i][j]=1
// 否则,则不是地面点,初始化为0,进行后续操作
diffX = fullCloud->points[upperInd].x - fullCloud->points[lowerInd].x;
diffY = fullCloud->points[upperInd].y - fullCloud->points[lowerInd].y;
diffZ = fullCloud->points[upperInd].z - fullCloud->points[lowerInd].z;
angle = atan2(diffZ, sqrt(diffX*diffX + diffY*diffY))*180/M_PI;
if (abs(angle - sensorMountAngle) <= 10)
{
groundMat.at<int8_t>(i, j) = 1;
groundMat.at<int8_t>(i + 1, j) = 1;
}
从顶视图看,这是1束激光(一共有16束)先后扫描到的两个点A和点B。OA和OB是扫描点和激光雷达传感器之间的距离。 我们可以在图中计算角。
上面的角可以按照激光雷达的水平角分辨率来设置阈值。
同样在竖直方向上,上下两个激光束之间扫描到的两个点也可以按照这种方法进行判断分类,只不过角度阈值设置为激光雷达垂直分辨率罢了。
根据前面的处理,我们得到了如下信息:
事实上是一个四邻域查找算法,算法伪代码如下:
//全局变量
label = 1
rangeMat(rangeMat为0的位置是没有标记过的)
void labelComponents(row, col, label)
{
queue_size = 1;
queue.push(row,col);
all_queue.push(row,col);
lineCountFlag[SCAN_ID] = false;//SCAN_ID=16雷达扫描线束总数
while(queue.size>0)
{
row, col = queue.top();
labelMat(row, col) = label;
for(iter : neighbors of (row, col))//遍历该元素的四邻域
{
row,col = iter.row, iter.col;
//标记过的点直接忽略
if (labelMat(row,col) != 0)
continue;
//得到分离物体的角度阈值
if(iter->position == horizon)
beta_threshold = 0.2;//激光雷达水平角分辨率
else
beta_threshold = 2;//激光雷达垂直角分辨率
//根据分割算法原理计算当前beta角
beta_angle = atan2(d2*sin(alpha), (d1 - d2*cos(alpha)));
if(beta_angle > beta_threshold)
{
queue.push(row, col);//将此neighbor加入queue
all_queue.push(row, col)
labelMat(row, col) = label;
lineCountFlag[this_scan_id] = true;//垂直方向标记计数
}
}
}
//分辨是否是有效聚类,如果是则增加labelCount,标记下一块,如果不是,就标记为outliers点
feasibleSegment = false;
if(all_queue.size>=30)// 如果聚类超过30个点,直接标记为一个可用聚类
feasibleSegment = true;
else if(all_queue.size>=5)// 如果聚类点数小于30大于等于5,统计竖直方向上的聚类点数
{
//遍历lineCountFlag[SCAN_ID]统计true的个数lineCount
if(lineCount>=3)
feasibleSegment = true;// 竖直方向上超过3个也将它标记为有效聚类
}
if(feasibleSegment==true)
{
label++;
}
else
{
for(iter : all_queue)
{
row, col = iter.row, iter.col;
labelMat(row, col) = 999999;//如果不是有效聚类则标记outliers点
}
}
}
IMU的重力加速度模型,在世界坐标系下表示为
回顾从I系到B系的坐标变换,此时我们使用ZYX欧拉角表示方法
所以,
imuHandler
runFeatureAssociation(200Hz)
Note: