1 /*
2  * Software License Agreement (BSD License)
3  *
4  *  Point Cloud Library (PCL) - www.pointclouds.org
5  *  Copyright (c) 2009-2012, Willow Garage, Inc.
6  *  Copyright (c) 2012-, Open Perception, Inc.
7  *  Copyright (c) 2014, RadiantBlue Technologies, Inc.
8  *
9  *  All rights reserved.
10  *
11  *  Redistribution and use in source and binary forms, with or without
12  *  modification, are permitted provided that the following conditions
13  *  are met:
14  *
15  *   * Redistributions of source code must retain the above copyright
16  *     notice, this list of conditions and the following disclaimer.
17  *   * Redistributions in binary form must reproduce the above
18  *     copyright notice, this list of conditions and the following
19  *     disclaimer in the documentation and/or other materials provided
20  *     with the distribution.
21  *   * Neither the name of the copyright holder(s) nor the names of its
22  *     contributors may be used to endorse or promote products derived
23  *     from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  *  POSSIBILITY OF SUCH DAMAGE.
37  *
38  * $Id$
39  */
40 
41 #include <pcl/point_types.h>
42 #include <pcl/io/pcd_io.h>
43 #include <pcl/common/generate.h>
44 #include <pcl/common/random.h>
45 #include <pcl/console/print.h>
46 #include <pcl/console/parse.h>
47 #include <pcl/console/time.h>
48 
49 using namespace pcl;
50 using namespace pcl::io;
51 using namespace pcl::common;
52 using namespace pcl::console;
53 
54 using PointType = PointXYZ;
55 using Cloud = PointCloud<PointXYZ>;
56 using ConstCloudPtr = const Cloud::ConstPtr;
57 
58 std::string default_distribution = "uniform";
59 float default_xmin = 0.0f;
60 float default_xmax = 1.0f;
61 float default_xmean = 0.0f;
62 float default_xstddev = 1.0f;
63 float default_ymin = 0.0f;
64 float default_ymax = 1.0f;
65 float default_ymean = 0.0f;
66 float default_ystddev = 1.0f;
67 float default_zmin = 0.0f;
68 float default_zmax = 1.0f;
69 float default_zmean = 0.0f;
70 float default_zstddev = 1.0f;
71 int default_size = 10000;
72 
73 void
printHelp(int,char ** argv)74 printHelp (int, char **argv)
75 {
76   print_error ("Syntax is: %s output.pcd <options>\n", argv[0]);
77   print_info ("  where options are:\n");
78   print_info ("                     -distribution X = the distribution to be used (options: uniform / normal) (default: ");
79   print_value ("%s", default_distribution.c_str ()); print_info (")\n");
80   print_info ("                     -size X = number of points in cloud (default: ");
81   print_value ("%d", default_size); print_info (")\n");
82   print_info ("                Options for uniform distribution:\n");
83   print_info ("                     -[x|y|z]min X = minimum for the [x|y|z] dimension (defaults: ");
84   print_value ("%f, %f, %f", default_xmin, default_ymin, default_zmin); print_info (")\n");
85   print_info ("                     -[x|y|z]max X = maximum for the [x|y|z] dimension (defaults: ");
86   print_value ("%f, %f, %f", default_xmax, default_ymax, default_zmax); print_info (")\n");
87   print_info ("                Options for normal distribution:\n");
88   print_info ("                     -[x|y|z]mean X = mean for the [x|y|z] dimension (defaults: ");
89   print_value ("%f, %f, %f", default_xmean, default_ymean, default_zmean); print_info (")\n");
90   print_info ("                     -[x|y|z]stddev X = standard deviation for the [x|y|z] dimension (defaults: ");
91   print_value ("%f, %f, %f", default_xstddev, default_ystddev, default_zstddev); print_info (")\n");
92 }
93 
94 void
saveCloud(const std::string & filename,const Cloud & output)95 saveCloud (const std::string &filename, const Cloud &output)
96 {
97   TicToc tt;
98   tt.tic ();
99 
100   print_highlight ("Saving "); print_value ("%s ", filename.c_str ());
101 
102   PCDWriter w;
103   w.writeBinaryCompressed (filename, output);
104 
105   print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", output.width * output.height); print_info (" points]\n");
106 }
107 
108 /* ---[ */
109 int
main(int argc,char ** argv)110 main (int argc, char** argv)
111 {
112   if (find_switch (argc, argv, "-h"))
113   {
114     printHelp (argc, argv);
115     return (0);
116   }
117 
118   print_info ("Generate a random point cloud. For more information, use: %s -h\n", argv[0]);
119 
120   if (argc < 2)
121   {
122     printHelp (argc, argv);
123     return (-1);
124   }
125 
126   // Command line parsing
127   std::string distribution = default_distribution;
128   float xmin = default_xmin;
129   float xmax = default_xmax;
130   float xmean = default_xmean;
131   float xstddev = default_xstddev;
132   float ymin = default_ymin;
133   float ymax = default_ymax;
134   float ymean = default_ymean;
135   float ystddev = default_ystddev;
136   float zmin = default_zmin;
137   float zmax = default_zmax;
138   float zmean = default_zmean;
139   float zstddev = default_zstddev;
140   int size = default_size;
141   parse_argument (argc, argv, "-distribution", distribution);
142   parse_argument (argc, argv, "-xmin", xmin);
143   parse_argument (argc, argv, "-xmax", xmax);
144   parse_argument (argc, argv, "-xmean", xmean);
145   parse_argument (argc, argv, "-xstddev", xstddev);
146   parse_argument (argc, argv, "-ymin", ymin);
147   parse_argument (argc, argv, "-ymax", ymax);
148   parse_argument (argc, argv, "-ymean", ymean);
149   parse_argument (argc, argv, "-ystddev", ystddev);
150   parse_argument (argc, argv, "-zmin", zmin);
151   parse_argument (argc, argv, "-zmax", zmax);
152   parse_argument (argc, argv, "-zmean", zmean);
153   parse_argument (argc, argv, "-zstddev", zstddev);
154   parse_argument (argc, argv, "-size", size);
155 
156   // Parse the command line arguments for .pcd files
157   std::vector<int> p_file_indices;
158   p_file_indices = parse_file_extension_argument (argc, argv, ".pcd");
159   if (p_file_indices.size () != 1)
160   {
161     print_error ("Need one output PCD file to continue.\n");
162     return (-1);
163   }
164 
165   // Perform the feature estimation
166   Cloud output;
167 
168   // Estimate
169   TicToc tt;
170   tt.tic ();
171 
172   print_highlight (stderr, "Computing ");
173 
174   if (distribution == "uniform")
175   {
176     CloudGenerator<pcl::PointXYZ, UniformGenerator<float> > generator;
177     std::uint32_t seed = static_cast<std::uint32_t> (time (nullptr));
178     UniformGenerator<float>::Parameters x_params (xmin, xmax, seed++);
179     generator.setParametersForX (x_params);
180     UniformGenerator<float>::Parameters y_params (ymin, ymax, seed++);
181     generator.setParametersForY (y_params);
182     UniformGenerator<float>::Parameters z_params (zmin, zmax, seed++);
183     generator.setParametersForZ (z_params);
184 
185     generator.fill (size, 1, output);
186   }
187   else if (distribution == "normal")
188   {
189     CloudGenerator<pcl::PointXYZ, NormalGenerator<float> > generator;
190     std::uint32_t seed = static_cast<std::uint32_t> (time (nullptr));
191     NormalGenerator<float>::Parameters x_params (xmean, xstddev, seed++);
192     generator.setParametersForX (x_params);
193     NormalGenerator<float>::Parameters y_params (ymean, ystddev, seed++);
194     generator.setParametersForY (y_params);
195     NormalGenerator<float>::Parameters z_params (zmean, zstddev, seed++);
196     generator.setParametersForZ (z_params);
197 
198     generator.fill (size, 1, output);
199   }
200   else
201   {
202     PCL_ERROR ("%s is not a valid generator! Quitting!\n", distribution.c_str ());
203     return (0);
204   }
205 
206   print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", output.width * output.height); print_info (" points]\n");
207 
208   // Save into the second file
209   saveCloud (argv[p_file_indices[0]], output);
210 }
211 
212