File: sim_terminal_demo.cpp

package info (click to toggle)
pcl 1.13.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 143,524 kB
  • sloc: cpp: 518,578; xml: 28,792; ansic: 13,676; python: 334; lisp: 93; sh: 49; makefile: 30
file content (223 lines) | stat: -rw-r--r-- 7,259 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/**
 * Demo program for simulation library
 * A virtual camera generates simulated point clouds
 * No visual output, point clouds saved to file
 *
 * three different demo modes:
 * 0 - static camera, 100 poses
 * 1 - circular camera flying around the scene, 16 poses
 * 2 - camera translates between 2 poses using slerp, 20 poses
 * pcl_sim_terminal_demo 2 ../../../../kmcl/models/table_models/meta_model.ply
 */

#include <pcl/common/time.h> // for getTime
#include <pcl/io/pcd_io.h>   // for PCDWriter
#include <pcl/memory.h>

#include "simulation_io.hpp"

#include <cmath>
#include <iostream>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

using namespace Eigen;
using namespace pcl;
using namespace pcl::console;
using namespace pcl::io;
using namespace pcl::simulation;

SimExample::Ptr simexample;

void
printHelp(int, char** argv)
{
  print_error("Syntax is: %s <mode 1,2 or 3> <filename>\n", argv[0]);
  print_info("acceptable filenames include vtk, obj and ply. ply can support colour\n");
}

// Output the simulated output to file:
void
write_sim_output(const std::string& fname_root)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr pc_out(new pcl::PointCloud<pcl::PointXYZRGB>);

  // Read Color Buffer from the GPU before creating PointCloud:
  // By default the buffers are not read back from the GPU
  simexample->rl_->getColorBuffer();
  simexample->rl_->getDepthBuffer();
  // Add noise directly to the CPU depth buffer
  simexample->rl_->addNoise();

  // Optional argument to save point cloud in global frame:
  // Save camera relative:
  // simexample->rl_->getPointCloud(pc_out);
  // Save in global frame - applying the camera frame:
  // simexample->rl_->getPointCloud(pc_out,true,simexample->camera_->getPose());
  // Save in local frame
  simexample->rl_->getPointCloud(pc_out, false, simexample->camera_->getPose());
  // TODO: what to do when there are more than one simulated view?

  if (!pc_out->points.empty()) {
    std::cout << pc_out->size() << " points written to file\n";

    pcl::PCDWriter writer;
    // writer.write ( string (fname_root + ".pcd"), *pc_out,	false);  /// ASCII
    writer.writeBinary(std::string(fname_root + ".pcd"), *pc_out);
    // std::cout << "finished writing file\n";
  }
  else {
    std::cout << pc_out->size() << " points in cloud, not written\n";
  }

  // simexample->write_score_image (simexample->rl_->getScoreBuffer (),
  //                               string (fname_root + "_score.png") );
  simexample->write_rgb_image(simexample->rl_->getColorBuffer(),
                              std::string(fname_root + "_rgb.png"));
  simexample->write_depth_image(simexample->rl_->getDepthBuffer(),
                                std::string(fname_root + "_depth.png"));
  // simexample->write_depth_image_uint (simexample->rl_->getDepthBuffer (),
  //                                    string (fname_root + "_depth_uint.png") );

  // Demo interacton with RangeImage:
  pcl::RangeImagePlanar rangeImage;
  simexample->rl_->getRangeImagePlanar(rangeImage);
}

// A 'halo' camera - a circular ring of poses all pointing at a center point
// @param: focus_center: the center points
// @param: halo_r: radius of the ring
// @param: halo_dz: elevation of the camera above/below focus_center's z value
// @param: n_poses: number of generated poses
void
generate_halo(
    std::vector<Eigen::Isometry3d, Eigen::aligned_allocator<Eigen::Isometry3d>>& poses,
    Eigen::Vector3d focus_center,
    double halo_r,
    double halo_dz,
    int n_poses)
{

  for (double t = 0; t < (2 * M_PI); t = t + (2 * M_PI) / ((double)n_poses)) {
    double x = halo_r * std::cos(t);
    double y = halo_r * sin(t);
    double z = halo_dz;
    double pitch = std::atan2(halo_dz, halo_r);
    double yaw = std::atan2(-y, -x);

    Eigen::Isometry3d pose;
    pose.setIdentity();
    Eigen::Matrix3d m;
    m = AngleAxisd(yaw, Eigen::Vector3d::UnitZ()) *
        AngleAxisd(pitch, Eigen::Vector3d::UnitY()) *
        AngleAxisd(0, Eigen::Vector3d::UnitZ());

    pose *= m;
    Vector3d v(x, y, z);
    v += focus_center;
    pose.translation() = v;
    poses.push_back(pose);
  }
  return;
}

int
main(int argc, char** argv)
{
  // 1. Parse arguments:
  print_info("Manually generate a simulated RGB-D point cloud using pcl::simulation. "
             "For more information, use: %s -h\n",
             argv[0]);
  if (argc < 3) {
    printHelp(argc, argv);
    return (-1);
  }
  int mode = atoi(argv[1]);

  // 2 Construct the simulation method:
  int width = 640;
  int height = 480;
  simexample = SimExample::Ptr(new SimExample(argc, argv, height, width));

  // 3 Generate a series of simulation poses:
  // -0 100 fixed poses
  // -1 a 'halo' camera
  // -2 slerp between two different poses
  std::vector<Eigen::Isometry3d, Eigen::aligned_allocator<Eigen::Isometry3d>> poses;
  if (mode == 0) {
    // Create a pose:
    Eigen::Isometry3d pose;
    pose.setIdentity();
    Matrix3d m;
    // ypr:
    m = AngleAxisd(-9.14989, Vector3d::UnitZ()) *
        AngleAxisd(0.20944, Vector3d::UnitY()) * AngleAxisd(0, Vector3d::UnitX());
    pose *= m;
    Vector3d v;
    v << 1.31762, 0.382931, 1.89533;
    pose.translation() = v;
    for (int i = 0; i < 100; i++) { // duplicate the pose 100 times
      poses.push_back(pose);
    }
  }
  else if (mode == 1) {
    Eigen::Vector3d focus_center(0, 0, 1.3);
    double halo_r = 4;
    double halo_dz = 2;
    int n_poses = 16;
    generate_halo(poses, focus_center, halo_r, halo_dz, n_poses);
  }
  else if (mode == 2) {
    Eigen::Isometry3d pose1;
    pose1.setIdentity();
    pose1.translation() << 1, 0.75, 2;
    Eigen::Matrix3d rot1;
    rot1 = AngleAxisd(M_PI, Eigen::Vector3d::UnitZ()) *
           AngleAxisd(M_PI / 10, Eigen::Vector3d::UnitY()) *
           AngleAxisd(0.0, Eigen::Vector3d::UnitZ()); // ypr
    pose1.rotate(rot1);

    Eigen::Isometry3d pose2;
    pose2.setIdentity();
    pose2.translation() << 1, -1, 3;
    Eigen::Matrix3d rot2;
    rot2 = AngleAxisd(3 * M_PI / 4, Eigen::Vector3d::UnitZ()) *
           AngleAxisd(M_PI / 4, Eigen::Vector3d::UnitY()) *
           AngleAxisd(0.0, Eigen::Vector3d::UnitZ()); // ypr
    pose2.rotate(rot2);

    int n_poses = 20;
    for (double i = 0; i <= 1; i += 1 / ((double)n_poses - 1)) {
      Eigen::Quaterniond rot3;
      Eigen::Quaterniond r1(pose1.rotation());
      Eigen::Quaterniond r2(pose2.rotation());
      rot3 = r1.slerp(i, r2);
      Eigen::Isometry3d pose;
      pose.setIdentity();
      Eigen::Vector3d trans3 = (1 - i) * pose1.translation() + i * pose2.translation();
      pose.translation() << trans3[0], trans3[1], trans3[2];
      pose.rotate(rot3);
      poses.push_back(pose);
    }
  }

  // 4 Do the simulation and write the output:
  double tic_main = getTime();
  for (std::size_t i = 0; i < poses.size(); i++) {
    std::stringstream ss;
    ss.precision(20);
    ss << "simcloud_" << i; // << ".pcd";
    double tic = getTime();
    simexample->doSim(poses[i]);

    write_sim_output(ss.str());
    std::cout << (getTime() - tic) << " sec\n";
  }
  std::cout << poses.size() << " poses simulated in " << (getTime() - tic_main)
            << "seconds\n";
  std::cout << (poses.size() / (getTime() - tic_main)) << "Hz on average\n";

  return 0;
}