41 : x_min_(
Params::kMinXRange),
42 x_max_(
Params::kMaxXRange),
43 y_min_(
Params::kMinYRange),
44 y_max_(
Params::kMaxYRange),
45 z_min_(
Params::kMinZRange),
46 z_max_(
Params::kMaxZRange) {}
51 std::string config_file =
55 const auto &model_info = param_.
info();
56 std::string model_path =
GetModelPath(model_info.name());
57 std::string weight_file =
58 GetModelFile(model_path, model_info.weight_file().file());
60 point_pillars_ptr_.reset(
64 model_info.framework(),
67 z_min_ = std::max(z_min_,
72 if (param_.has_plugins()) {
73 const auto &plugin = param_.
plugins();
74 const auto &name = plugin.
name();
79 AINFO <<
"Failed to find down_sample plugin: " << name <<
", skipped";
85 if (!down_sample_->Init(option)) {
86 AINFO <<
"Failed to init down_sample plugin: " << name <<
", skipped";
97 if (frame ==
nullptr) {
98 AERROR <<
"Input null frame ptr.";
101 if (frame->
cloud ==
nullptr) {
102 AERROR <<
"Input null frame cloud.";
105 if (frame->
cloud->size() == 0) {
106 AERROR <<
"Input none points.";
111 original_cloud_ = frame->
cloud;
113 lidar_frame_ref_ = frame;
126 cur_cloud_ptr_ = std::shared_ptr<base::PointFCloud>(
132 if (DownSamplePointCloudBeams(
133 original_cloud_, downsample_beams_cloud_ptr,
135 cur_cloud_ptr_ = downsample_beams_cloud_ptr;
137 AWARN <<
"Down-sample beams factor must be >= 1. Cancel down-sampling."
146 ACHECK(down_sample_ !=
nullptr);
147 down_sample_->Process(down_sample_options, cur_cloud_ptr_);
149 downsample_time_ = timer.
toc(
true);
151 num_points = cur_cloud_ptr_->size();
152 AINFO <<
"num points before fusing: " << num_points;
155 cur_cloud_ptr_->mutable_points_timestamp()->assign(cur_cloud_ptr_->size(),
160 while (!prev_world_clouds_.empty() &&
161 frame->
timestamp - prev_world_clouds_.front()->get_timestamp() >
163 prev_world_clouds_.pop_front();
167 std::make_shared<base::PointDCloud>();
168 for (
size_t i = 0; i < cur_cloud_ptr_->size(); ++i) {
169 auto& pt = cur_cloud_ptr_->at(i);
170 Eigen::Vector3d trans_point(pt.x, pt.y, pt.z);
173 world_point.x = trans_point(0);
174 world_point.y = trans_point(1);
175 world_point.z = trans_point(2);
176 world_point.intensity = pt.intensity;
177 cur_world_cloud_ptr->push_back(world_point);
179 cur_world_cloud_ptr->set_timestamp(frame->
timestamp);
182 for (
auto& prev_world_cloud_ptr : prev_world_clouds_) {
183 num_points += prev_world_cloud_ptr->size();
185 FuseCloud(cur_cloud_ptr_, prev_world_clouds_);
188 while (
static_cast<int>(prev_world_clouds_.size()) >=
190 prev_world_clouds_.pop_front();
192 prev_world_clouds_.emplace_back(cur_world_cloud_ptr);
194 AINFO <<
"num points after fusing: " << num_points;
195 fuse_time_ = timer.
toc(
true);
200 std::vector<int> point_indices = GenerateIndices(0, num_points,
true);
203 cur_cloud_ptr_ = shuffle_cloud_ptr;
205 shuffle_time_ = timer.
toc(
true);
208 float* points_array =
210 CloudToArray(cur_cloud_ptr_, points_array,
212 cloud_to_array_time_ = timer.
toc(
true);
215 std::vector<float> out_detections;
216 std::vector<int> out_labels;
217 point_pillars_ptr_->DoInference(points_array, num_points, &out_detections,
219 inference_time_ = timer.
toc(
true);
223 &out_detections, &out_labels);
224 collect_time_ = timer.
toc(
true);
226 AINFO <<
"PointPillars: "
228 <<
"down sample: " << downsample_time_ <<
"\t"
229 <<
"fuse: " << fuse_time_ <<
"\t"
230 <<
"shuffle: " << shuffle_time_ <<
"\t"
231 <<
"cloud_to_array: " << cloud_to_array_time_ <<
"\t"
232 <<
"inference: " << inference_time_ <<
"\t"
233 <<
"collect: " << collect_time_;
235 delete[] points_array;
240 float* out_points_array,
241 const float normalizing_factor) {
242 for (
size_t i = 0; i < pc_ptr->size(); ++i) {
243 const auto& point = pc_ptr->at(i);
247 float intensity = point.intensity;
248 if (z < z_min_ || z > z_max_ || y < y_min_ || y > y_max_ || x < x_min_ ||
256 intensity / normalizing_factor;
259 static_cast<float>(pc_ptr->points_timestamp(i));
263void MaskPillarsDetection::FuseCloud(
265 const std::deque<base::PointDCloudPtr>& fuse_clouds) {
266 for (
auto iter = fuse_clouds.rbegin(); iter != fuse_clouds.rend(); ++iter) {
267 double delta_t = lidar_frame_ref_->
timestamp - (*iter)->get_timestamp();
269 for (
size_t i = 0; i < (*iter)->size(); ++i) {
270 auto& point = (*iter)->at(i);
271 Eigen::Vector3d trans_point(point.x, point.y, point.z);
274 pt.
x =
static_cast<float>(trans_point(0));
275 pt.y =
static_cast<float>(trans_point(1));
276 pt.z =
static_cast<float>(trans_point(2));
277 pt.intensity =
static_cast<float>(point.intensity);
279 out_cloud_ptr->push_back(pt, delta_t);
284std::vector<int> MaskPillarsDetection::GenerateIndices(
int start_index,
288 std::vector<int> indices(size);
289 std::iota(indices.begin(), indices.end(), start_index);
294 std::shuffle(indices.begin(), indices.end(),
295 std::default_random_engine(seed));
300void MaskPillarsDetection::GetObjects(
301 std::vector<std::shared_ptr<Object>>* objects,
const Eigen::Affine3d& pose,
302 std::vector<float>* detections, std::vector<int>* labels) {
303 int num_objects = detections->size() /
307 base::ObjectPool::Instance().BatchGet(num_objects, objects);
309 for (
int i = 0; i < num_objects; ++i) {
310 auto&
object = objects->at(i);
314 float x = detections->at(
316 float y = detections->at(
318 float z = detections->at(
320 float dx = detections->at(
322 float dy = detections->at(
324 float dz = detections->at(
326 float yaw = detections->at(
329 yaw = std::atan2(sinf(yaw), cosf(yaw));
334 object->direction[0] = cosf(yaw);
335 object->direction[1] = sinf(yaw);
336 object->direction[2] = 0;
337 object->lidar_supplement.is_orientation_ready =
true;
340 object->lidar_supplement.num_points_in_roi = 8;
341 object->lidar_supplement.on_use =
true;
342 object->lidar_supplement.is_background =
false;
343 float roll = 0, pitch = 0;
344 Eigen::Quaternionf quater =
345 Eigen::AngleAxisf(roll, Eigen::Vector3f::UnitX()) *
346 Eigen::AngleAxisf(pitch, Eigen::Vector3f::UnitY()) *
347 Eigen::AngleAxisf(yaw, Eigen::Vector3f::UnitZ());
348 Eigen::Translation3f translation(x, y, z);
349 Eigen::Affine3f affine3f = translation * quater.toRotationMatrix();
350 for (
float vx :
std::vector<float>{dx / 2, -dx / 2}) {
351 for (
float vy :
std::vector<float>{dy / 2, -dy / 2}) {
352 for (
float vz :
std::vector<float>{0, dz}) {
353 Eigen::Vector3f v3f(vx, vy, vz);
354 v3f = affine3f * v3f;
359 object->lidar_supplement.cloud.push_back(point);
361 Eigen::Vector3d trans_point(point.x, point.y, point.z);
362 trans_point = pose * trans_point;
364 world_point.x = trans_point(0);
365 world_point.y = trans_point(1);
366 world_point.z = trans_point(2);
367 object->lidar_supplement.cloud_world.push_back(world_point);
373 object->lidar_supplement.raw_probs.push_back(std::vector<float>(
375 object->lidar_supplement.raw_classification_methods.push_back(
Name());
376 object->sub_type = GetObjectSubType(labels->at(i));
378 object->lidar_supplement.raw_probs.back()[
static_cast<int>(
object->type)] =
381 object->type_probs.assign(object->lidar_supplement.raw_probs.back().begin(),
382 object->lidar_supplement.raw_probs.back().end());
#define PERCEPTION_REGISTER_LIDARDETECTOR(name)
static PluginManager * Instance()
get singleton instance of PluginManager
std::shared_ptr< Base > CreateInstance(const std::string &derived_class)
create plugin instance of derived class based on Base
static std::string GetFullClassName(const std::string &class_name)
Given the class name of perception module, combine the namespace "apollo::perception::lidar::" with i...
MaskPillarsDetection()
Construct a new Mask Pillars Detection object
bool Init(const LidarDetectorInitOptions &options=LidarDetectorInitOptions()) override
Init of Mask Pillars Detection object
std::string Name() const override
Name of Mask Pillars Detection module
bool Detect(const LidarDetectorOptions &options, LidarFrame *frame) override
Detect foregorund objects using maskpillars
double toc(bool reset=false)
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
std::shared_ptr< PointDCloud > PointDCloudPtr
std::shared_ptr< PointFCloud > PointFCloudPtr
const std::map< ObjectSubType, ObjectType > kSubType2TypeMap
ObjectSubType mapping
std::string GetModelFile(const std::string &model_name, const std::string &file_name)
Get the model file path by model path and file name
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
std::string GetModelPath(const std::string &model_name)
Get the model path by model name, search from APOLLO_MODEL_PATH
optional float nms_overlap_threshold
optional float score_threshold
optional int32 num_output_box_feature
optional bool enable_downsample_beams
optional bool enable_fuse_frames
optional int32 max_num_points
optional int32 num_point_feature
optional bool reproduce_result_mode
optional bool enable_downsample_pointcloud
optional bool enable_shuffle_points
optional double fuse_time_interval
optional double ground_removal_height
optional bool enable_ground_removal
optional int32 downsample_beams_factor
optional double normalizing_factor
optional int32 num_fuse_frames
Eigen::Affine3d lidar2world_pose
std::shared_ptr< base::AttributePointCloud< base::PointD > > world_cloud
std::vector< std::shared_ptr< base::Object > > segmented_objects
std::shared_ptr< base::AttributePointCloud< base::PointF > > cloud
optional common::PointCloudPostProcess postprocess
optional common::ModelInfo info
optional PluginParam plugins
optional common::PointCloudPreProcess preprocess