[Documentation] [TitleIndex] [WordIndex

包括的なPCLのチュートリアルのリストは、PCLの 外部ウェブサイトで見ることができます. あなたが見たいであろうものは以下のようなものがあると思います。

ROSにおけるpcl全般の更なる情報(例えば、point clouodデータの型, パブリッシュ/サブスクライブ)などはROS/PCL overviewで見ることができます.

下記のチュートリアルでは既存のいずれかの http://pointclouds.org のチュートリアルをnodeやnodeletを用いるROS ecosystemでどのように使用するかについて説明します.

How to use a PCL tutorial in ROS

ROSパッケージの作成

roscreate-pkg my_pcl_tutorial pcl pcl_ros roscpp sensor_msgs

catkin_create_pkg my_pcl_tutorial pcl pcl_ros roscpp sensor_msgs

これで必要な依存性を持ったROSパッケージができます

コードの骨組みの作成

src/example.cppという名前の空のファイルを作成して以下のコードを貼り付けましょう

   1 #include <ros/ros.h>
   2 #include <sensor_msgs/PointCloud2.h>
   3 // PCL specific includes
   4 #include <pcl/ros/conversions.h>
   5 #include <pcl/point_cloud.h>
   6 #include <pcl/point_types.h>
   7 
   8 ros::Publisher pub;
   9 
  10 void 
  11 cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)
  12 {
  13   // ... do data processing
  14 
  15   sensor_msgs::PointCloud2 output;
  16   // Publish the data
  17   pub.publish (output);
  18 }
  19 
  20 int
  21 main (int argc, char** argv)
  22 {
  23   // Initialize ROS
  24   ros::init (argc, argv, "my_pcl_tutorial");
  25   ros::NodeHandle nh;
  26 
  27   // Create a ROS subscriber for the input point cloud
  28   ros::Subscriber sub = nh.subscribe ("input", 1, cloud_cb);
  29 
  30   // Create a ROS publisher for the output point cloud
  31   pub = nh.advertise<sensor_msgs::PointCloud2> ("output", 1);
  32 
  33   // Spin
  34   ros::spin ();
  35 }

上記のコードはROSを初期化しPointCloud2データへのサブスクライバとパブリシャを作るだけです

CMakeLists.txtにソースファイルを追加する

あなたが新しく作成したパッケージのCMakeLists.txtを編集して下記を追加してください

rosbuild_add_executable (example src/example.cpp)

add_executable(example src/example.cpp)
target_link_libraries(example ${catkin_LIBRARIES})

PCLチュートリアルからソースコードをダウンロードする

バージョン2.0までのすべてのPCLは点群データの2種類の表現法を持っています

下記の2つのコード例は両方のフォーマットについて論じています

sensor_msgs/PointCloud2

sensor_msgs/PointCloud2フォーマットはROSメッセージとして設計されており, ROSアプリケーションにはより好ましい選択です. 下記の例では3Dグリッドを用いてPointCloud2構造の解像度を下げ, 相当に入力データの点の数を減らしています.

上記のコードの骨組みにこの能力を持たせるために, 以下のステップを行ってください

   1   // Create the filtering object
   2   pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
   3   sor.setInputCloud (cloud);
   4   sor.setLeafSize (0.01, 0.01, 0.01);
   5   sor.filter (*cloud_filtered);

これらの行では, 入力データは cloudと呼ばれ, 出力はcloud_filteredと呼ばれます. コールバック関数を下記のように書き換えて, これらの行を上のコード片にコピーしましょう:

   1 #include <pcl/filters/voxel_grid.h>
   2 
   3 ...
   4 
   5 void 
   6 cloud_cb (const sensor_msgs::PointCloud2ConstPtr& cloud)
   7 {
   8   sensor_msgs::PointCloud2 cloud_filtered;
   9 
  10   // Perform the actual filtering
  11   pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;
  12   sor.setInputCloud (cloud);
  13   sor.setLeafSize (0.01, 0.01, 0.01);
  14   sor.filter (cloud_filtered);
  15 
  16   // Publish the data
  17   pub.publish (cloud_filtered);
  18 }

別のチュートリアルではしばしば各々異なった変数名を入出力に用いているので, チュートリアルのコードをあなた自身のROSノードに統合する場合はわずかにコードを変更する必要がある可能性があることを覚えておいてください. 今回の場合, コピーしたチュートリアルのコードと一致させるため変数名をinputからcloudに, そしてoutputからcloud_filteredに変更しなければならなかったことに注目してください

出力ファイルを保存してビルドしましょう:

$ rosmake my_pcl_tutorial

$ cd %TOP_DIR_YOUR_CATKIN_HOME%
$ catkin_make

そして動かしましょう:

rosrun my_pcl_tutorial example input:=/narrow_stereo_textured/points2

もしコピーペーストしてを保存したいなら, この例のソースファイルをダウンロードできますhere.

pcl/PointCloud<T>

pcl/PointCloud<T> フォーマットはPCL点群フォーマットの内部を表現します. モジュール性と効率性を考えて, フォーマットは点の種類によるテンプレートになっており, PCLはSSEで整列したテンプレートの共通型のリストを提供します. 以下の例では, シーン内で見つかったもっとも大きい平面のplanar係数を見積もります.

上のコード骨組みにこの能力を付加するため, 以下のステップにしたがってください:

   1   pcl::ModelCoefficients coefficients;
   2   pcl::PointIndices inliers;
   3   // Create the segmentation object
   4   pcl::SACSegmentation<pcl::PointXYZ> seg;
   5   // Optional
   6   seg.setOptimizeCoefficients (true);
   7   // Mandatory
   8   seg.setModelType (pcl::SACMODEL_PLANE);
   9   seg.setMethodType (pcl::SAC_RANSAC);
  10   seg.setDistanceThreshold (0.01);
  11 
  12   seg.setInputCloud (cloud.makeShared ());
  13   seg.segment (inliers, coefficients);

これらの行では, 入力データセットはcloudと呼ばれ, pcl::PointCloud<pcl::PointXYZ>型を持っており, 出力は平面が含む点のインデックスの集合とplane係数で表現されます. cloud.makeShared()cloudオブジェクトへの boost shared_ptr オブジェクトを生成します (the pcl::PointCloud API ドキュメントを見てください).

コールバック関数を下記のように書き換えて, これらの行を上記のコード片にコピーしましょう:

   1 #include <pcl/sample_consensus/model_types.h>
   2 #include <pcl/sample_consensus/method_types.h>
   3 #include <pcl/segmentation/sac_segmentation.h>
   4 
   5 ...
   6 
   7 void 
   8 cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)
   9 {
  10   // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
  11   pcl::PointCloud<pcl::PointXYZ> cloud;
  12   pcl::fromROSMsg (*input, cloud);
  13 
  14   pcl::ModelCoefficients coefficients;
  15   pcl::PointIndices inliers;
  16   // Create the segmentation object
  17   pcl::SACSegmentation<pcl::PointXYZ> seg;
  18   // Optional
  19   seg.setOptimizeCoefficients (true);
  20   // Mandatory
  21   seg.setModelType (pcl::SACMODEL_PLANE);
  22   seg.setMethodType (pcl::SAC_RANSAC);
  23   seg.setDistanceThreshold (0.01);
  24 
  25   seg.setInputCloud (cloud.makeShared ());
  26   seg.segment (inliers, coefficients);
  27 
  28   // Publish the model coefficients
  29   pub.publish (coefficients);
  30 }

  • 私たちは最初の2行で sensor_msgs/PointCloud2 から pcl/PointCloud<T> への変換ステップを追加し, また発行する変数名を output から coefficientsに変更したことに注目してください.

加えて, 今私たちは点群データよりもplanar model係数を発行しているので, パブリシャの型を

  // Create a ROS publisher for the output point cloud
  pub = nh.advertise<sensor_msgs::PointCloud2> ("output", 1);

から:

  // Create a ROS publisher for the output model coefficients
  pub = nh.advertise<pcl::ModelCoefficients> ("output", 1);

へ変えましょう.

出力ファイルを保存して, 上記のコードをコンパイルして動かしましょう:

rosrun my_pcl_tutorial example input:=/narrow_stereo_textured/points2

先の例と同様, もし少しの手間を省きたければ, この例のソースファイルをダウンロードすることができますhere.


2024-03-23 12:39