pcl的初步使用(ROS)
ROS里面已經(jīng)預裝好了pcl,和一些與pcl之間的轉(zhuǎn)換,我們接下來看看如何在ros里面使用pcl.。
總的來說,PCL包含了一個很重要得到數(shù)據(jù)結(jié)構(gòu),叫PointCloud,這是一個模板類,把點的類型作為模板參數(shù)。
下面是最重要的在點云里面的公共域
header 這個域是pcl::PCLHeader類型和指定點云的獲取時間。
points:這個域是std::vector<PointT,..>類型,是點云存儲的容器。PointT是類模板參數(shù)。
width:這個域指定點云的寬度在組織一個圖像的時候,否則只有一個。
height:這個域指定點云的高度,沒有指定則只有一個。
is_dense:這個域指定點云是否包含無效值(infinite或者NaN)
sensor_origin_:這個域是Eigen::Vector4f 類型,它定義 了傳感器的獲取姿勢就一個區(qū)域的轉(zhuǎn)換而言。
sensor_orientation_:這個域是Eigen::Quaternion類型,他定義了sensor作為一個旋轉(zhuǎn)的角度而言。
了解了點云的數(shù)據(jù)結(jié)構(gòu)以后,下面就可以了解不同點云的類型,pcl是怎么工作的,已及pcl與ROS間的關系。
不同的點云類型
前面所說的,pcl::PointCloud包含一個域,它作為點的容器,這個域是PointT類型的,這個域是PointT類型的是pcl::PointCloud類的模板參數(shù),定義了點云的存儲類型。PCL定義了很多類型的點,下面是一些最常用的:
pcl::PointXYZ 這是最簡單的點的類型,存儲著點的x,y,z信息。
pcl::PointXYZI:這個類型的點是和前面的那個很相似的,但是他也包含一個域描述了點的密集程度。另外還有兩個其他的標準的特殊的點的類型:第一個是pcl::InterestPoint,它有一個域去存儲長處而不是密集度。pcl::PointWithRange,存儲了點的范圍(深度).
pcl::PointXYZRGBA:這個類型的點存儲了3D信息同時和RGB與Alpha(透明度)
pcl::PointXYZRGB
pcl::Normal:這是一個最常用的點的類型,它代表了給定點的?曲面法線(normal翻譯為法線有點奇怪)和曲率的測量。
pcl::PointNormal:這個類型和前面那個一樣。只不過它多了坐標(x,y,z)。他的變體有PointXYZRGBNormal和PointXYZINormal,就像名字所說的一樣,前者包含顏色,后者包含密集度。
除了以上這些常用的點的類型,還有很多 標準的其他的PCL類型,比如PointWithViewpoint,MomentInvariants,Boundary,PrincipalCurvatures,Histogram.更重要的是在PCL里面除了這些類型,用戶還可以自己定義自己的類型。
PCL里面的算法
PCL用一個很特別的設計模式貫穿整個庫去定義點云處理算法。總體來說,上面這些類型的算法是高度配置的,為了開發(fā)他們的潛能,庫必須要提供一個機制對用戶來指定哪些參數(shù)是需要的,哪些是默認的。
為了解決這個問題,PCL的開發(fā)者決定去使每個算法屬于一個特定共同點下的同層次的類。這個方式允許PCL開發(fā)者通過派生和添加參數(shù)值的方式,復用存在的算法。它也允許用戶去提供參數(shù)值,剩余的是默認值。下面是一小段代碼當使用PCL算法時看起來的樣子:
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::Po
intXYZ>);?
pcl::PointCloud<pcl::PointXYZ>::Ptr result(new pcl::PointCloud<pcl::P
ointXYZ>);
pcl::Algorithm<pcl::PointXYZ> algorithm;
algorithm.setInputCloud(cloud);
algorithm.setParameter(1.0);
algorithm.setAnotherParameter(0.33);
algorithm.process (*result);
PCL對ROS的接口
PCL對ROS的接口提供PCL數(shù)據(jù)結(jié)構(gòu)的交流,通過通過ROS提供的以消息為基礎的交流系統(tǒng)。為了這么做,有幾個消息類型交流系統(tǒng)提供的去把點云和其他數(shù)據(jù)進行涵蓋。為了結(jié)合這些數(shù)據(jù)類型,一系列的轉(zhuǎn)換函數(shù)提供用來轉(zhuǎn)換原始的PCL數(shù)據(jù)類型成消息型。一些最有用的message類型列舉在下面。
std_msgs:Header:這不是真的消息類型,但是他用在Ros消息里面的每一個部分。它包含了消息被發(fā)送的時間和序列號和框名。PCL等于pcl::Header類型
sensor_msgs::PointCloud2:這是最重要的類型。這個消息通常是用來轉(zhuǎn)換pcl::PointCloud類型的,然而,它是很重要的去了解pcl::PCLPointCloud2這個類型,因為前面版本的可能被廢除。
pcl_msgs::PointIndices:這個類型存儲屬于點云里面的點的下標,在pcl里面等于pcl::PointIndices
pcl_msgs::PolygonMesh這個類型包括消息需要描述多邊形網(wǎng)眼,就是頂點和邊,在pcl里面等于pcl::PolygonMesh
pcl_msgs::Vertices:這個類型包含了一系列的頂點作為一個數(shù)組的下標,來描述一個多邊形。在pcl里面等于pcl::Vertices
pcl_msgs::ModelCoefficients:這存儲了一個模型的不同的系數(shù),比如描述一個平面需要4個系數(shù)。在PCL里面等于pcl::ModelCoefficients
上面的數(shù)據(jù)可以從PCL轉(zhuǎn)成ROS里面的PCL。所有的函數(shù)有一個類似的特征,意味著一旦我們知道這樣去轉(zhuǎn)換一個類型,我們就能學會轉(zhuǎn)換其他的類型。下面的函數(shù)是在pcl_conversions命名空間里面提供的函數(shù)
void fromPCL(const <PCL Type> &, <ROS Message type> &);
void moveFromPCL(<PCL Type> &, <ROS Message type> &);
void toPCL(const <ROS Message type> &, <PCL Type> &);
void moveToPCL(<ROS Message type> &, <PCL?Type> &);
這里,PCL類型必須被替換成先前指定的PCL類型和ROS里面相應的類型。sensor_msgs::PointCloud2有一個特定的函數(shù)集去執(zhí)行轉(zhuǎn)換
void toROSMsg(const pcl::PointCloud<T> &, sensor_msgs::PointCloud2 &);
void fromROSMsg(const sensor_msgs::PointCloud2 &, pcl::PointCloud<T>
&);
void moveFromROSMsg(sensor_msgs::PointCloud2 &, pcl::PointCloud<T> &);
你可能會對每個函數(shù)的不同感到奇怪還有它的move版本。其實是正常版本執(zhí)行的是一個深拷貝(完全拷貝),而move版的是淺拷貝,并使源數(shù)據(jù)作廢。
上面廢話了這么多,可以來寫代碼了,不過小伙伴們不要激動,這不是雖然萬惡的"hello world",但也沒啥特殊的效果。
先建一個包
catkin_create_pkg chapter6_tutorials pcl_conversions pcl_ros pcl_msgs
sensor_msgs
然后再建一個cpp文件,叫pcl_sample的cpp文件
/*
*File Name pcl_sample
*Author ? ? ? ? shukai
*Date ? ? ? ? ? Mon Apr ?4 09:29:48 CDT 2016
*Description ? ?A simple pcl demo
*/
#include<ros/ros.h>
#include<pcl/point_cloud.h>
#include<pcl_ros/point_cloud.h>
#include<pcl_conversions/pcl_conversions.h>
#include<sensor_msgs/PointCloud2.h>
int main(int argc,char** argv)
{
ros::init(argc,argv,"pcl_sample");
ros::NodeHandle nh;
ros::Publisher pcl_pub = nh.advertise<sensor_msgs::PointCloud2>("pcl_output",1);
sensor_msgs::PointCloud2 output;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
cloud->width = 100;
cloud->height= 1;
cloud->points.resize(cloud->width*cloud->height);
//Convert the cloud to ROS message
pcl::toROSMsg(*cloud,output);
pcl_pub.publish(output);
ros::spinOnce();
return 0;
}
這個程序的主要目的是建立一個有效的使用PCL的節(jié)點,同時看看編譯有沒有什么問題。
然后接著在CMakelist.txt里面加入以下的東西
尋找系統(tǒng)里面的PCL庫
find_package(PCL REQUIRED)
include_directories(include ${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS}
然后下面是生成可執(zhí)行文件和鏈接相應的庫
add_executable(pcl_sample src/pcl_sample.cpp)
target_link_libraries(pcl_sample ${catkin_LIBRARIES} ${PCL_LIBRARIES})
最后用catkin_make就可以了
總結(jié),ros里面可以用pcl的庫,但是往往需要對其轉(zhuǎn)換,比如上面的pcl::toROSMsg(*cloud,output);把pcl里面的pcl::PointCloud<pcl::PointXYZ>轉(zhuǎn)換成ros里面的sensor_msgs::PointCloud2這個類型。
總結(jié)
以上是生活随笔為你收集整理的pcl的初步使用(ROS)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Css轮廓
- 下一篇: weex监听android返回键,wee