Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
performance_test.cpp
Go to the documentation of this file.
1#include <gtest/gtest.h>
2#include <pcl/io/pcd_io.h>
3#include <pcl_conversions/pcl_conversions.h>
4
5#include <chrono>
6#include <ctime>
7#include <filesystem>
8#include <fstream>
9#include <iostream>
10#include <sstream>
11#include <string>
12
13#include "clustering/dbscan.hpp"
16
22 long long initial_n_points;
23 long long RANSAC_time;
25 long long DBSCAN_time;
26 long long ConeDif_time;
27 long long Total_time;
29 long long blues;
30 long long yellows;
31 long long undefineds;
33 double RANSAC_eps;
34};
35
40class PerceptionPerformanceTest : public ::testing::Test {
41public:
45 void SetUp() override {
46 pcl_cloud = std::make_unique<pcl::PointCloud<pcl::PointXYZI>>();
47 ground_removal = std::make_unique<RANSAC>(RANSAC_eps, RANSAC_Iter);
49 cone_differentiator = std::make_unique<LeastSquaresDifferentiation>();
50 }
51
57 auto now = std::chrono::system_clock::now();
58 std::time_t now_time = std::chrono::system_clock::to_time_t(now);
59 std::tm now_tm;
60 localtime_r(&now_time, &now_tm);
61
62 std::stringstream ss;
63 ss << std::put_time(&now_tm, "%Y-%m-%d-%H:%M");
64 return ss.str();
65 }
66
83 void writeToFile(const PerceptionExecutionData& executionTime) {
84 bool fileExists = std::filesystem::exists(output_statistics_path_file);
85
86 std::ofstream csv_file(output_statistics_path_file, std::ios::app);
87 if (!fileExists) {
88 csv_file << "Initial Number of Points,Conversion Duration,"
89 << "RANSAC Epsilon,RANSAC Number Iterations,"
90 << "Number of Points after RANSAC,RANSAC Duration(ms),"
91 << "DBSCAN Distance Threshold,DBSCAN Neighbours Threshold,"
92 << "Number of Generated Clusters,"
93 << "DBSCAN Duration(ms),"
94 << "Number of Blue Cones,Number of Yellow Cones,"
95 << "Number of Undefined Cones,ConeDifferentiation Duration(ms),"
96 << "Total Duration(ms)\n";
97 }
98
99 csv_file << std::fixed << std::setprecision(6);
100 csv_file << executionTime.initial_n_points << "," << std::fixed << std::setprecision(3)
101 << executionTime.conversion_duration << "," << RANSAC_eps << "," << RANSAC_Iter << ","
102 << executionTime.ground_removed_size << "," << std::fixed << std::setprecision(3)
103 << executionTime.RANSAC_time << "," << DBSCAN_dist_threshold << ","
104 << executionTime.DBSCAN_time << "," << executionTime.generatedClusters << ","
105 << std::fixed << std::setprecision(3) << executionTime.DBSCAN_time << ","
106 << executionTime.blues << "," << executionTime.yellows << ","
107 << executionTime.undefineds << "," << std::fixed << std::setprecision(3)
108 << executionTime.ConeDif_time << "," << std::fixed << std::setprecision(3)
109 << executionTime.Total_time << std::endl;
110
111 csv_file.close();
112 }
113 std::string output_statistics_path_file = "../../performance/exec_time/perception/perception_" +
115 std::string inputFilesPaths = "../../src/perception/test/point_clouds/";
116
117 std::unique_ptr<GroundRemoval> ground_removal;
118 std::unique_ptr<Clustering> clustering;
119 std::unique_ptr<ConeDifferentiation> cone_differentiator;
120 pcl::PointCloud<pcl::PointXYZI>::Ptr pcl_cloud;
121
122 float RANSAC_eps = 0.1;
123 int RANSAC_Iter = 20;
124
127};
128
133 for (long unsigned int it = 0; it <= 7; it++) {
134 std::stringstream ss;
135 ss << inputFilesPaths << "PointCloud" << it << ".pcd";
136 std::string file_name = ss.str();
137
138 struct PerceptionExecutionData executionTime;
139
140 // Point cloud loading and transform into ROS msg
141 pcl::io::loadPCDFile<pcl::PointXYZI>(file_name, *pcl_cloud);
142 sensor_msgs::msg::PointCloud2 msg;
143 pcl::toROSMsg(*pcl_cloud, msg);
144 pcl_cloud.reset(new pcl::PointCloud<pcl::PointXYZI>);
145
146 auto start_time = std::chrono::high_resolution_clock::now();
147
148 pcl::fromROSMsg(msg, *pcl_cloud);
149
150 auto conversion_time = std::chrono::high_resolution_clock::now();
151
152 executionTime.conversion_duration =
153 std::chrono::duration_cast<std::chrono::milliseconds>(start_time - conversion_time).count();
154
155 const pcl::PointCloud<pcl::PointXYZI>::Ptr ground_removed_cloud(
156 new pcl::PointCloud<pcl::PointXYZI>);
157
158 Plane plane;
159 const SplitParameters split_params;
160
161 ground_removal->ground_removal(pcl_cloud, ground_removed_cloud, plane, split_params);
162
163 auto ransac_time = std::chrono::high_resolution_clock::now();
164 executionTime.RANSAC_time =
165 std::chrono::duration_cast<std::chrono::milliseconds>(ransac_time - conversion_time)
166 .count();
167
168 std::vector<Cluster> clusters;
169 clustering->clustering(ground_removed_cloud, &clusters);
170
171 auto dbscan_time = std::chrono::high_resolution_clock::now();
172 executionTime.DBSCAN_time =
173 std::chrono::duration_cast<std::chrono::milliseconds>(dbscan_time - ransac_time).count();
174
175 executionTime.blues = 0;
176 executionTime.yellows = 0;
177 executionTime.undefineds = 0;
178 for (auto cluster : clusters) {
179 cone_differentiator->coneDifferentiation(&cluster);
180 std::string color = cluster.get_color();
181 if (color == "blue")
182 executionTime.blues++;
183 else if (color == "yellow")
184 executionTime.yellows++;
185 else
186 executionTime.undefineds++;
187 }
188
189 auto end_time = std::chrono::high_resolution_clock::now();
190 executionTime.ConeDif_time =
191 std::chrono::duration_cast<std::chrono::milliseconds>(end_time - dbscan_time).count();
192
193 executionTime.Total_time =
194 std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(end_time - start_time)
195 .count();
196
197 executionTime.initial_n_points = pcl_cloud->points.size();
198 executionTime.ground_removed_size = ground_removed_cloud->points.size();
199
200 writeToFile(executionTime);
201 }
202}
Test fixture for performance testing of perception algorithms.
std::unique_ptr< GroundRemoval > ground_removal
std::unique_ptr< Clustering > clustering
void writeToFile(const PerceptionExecutionData &executionTime)
Write performance statistics to a CSV file.
std::unique_ptr< ConeDifferentiation > cone_differentiator
std::string get_current_date_time_as_string()
Get current date and time as a string.
pcl::PointCloud< pcl::PointXYZI >::Ptr pcl_cloud
void SetUp() override
Set up the test fixture.
The Plane class represents a 3D plane defined by its equation ax + by + cz + d = 0.
Definition plane.hpp:12
TEST_F(PerceptionPerformanceTest, TestPerformance)
Test case for performance testing of perception algorithms.
Struct to store data related to perception execution.
long long DBSCAN_time
Time taken by DBSCAN algorithm.
long long initial_n_points
Initial number of points.
long long ground_removed_size
Size of ground removed.
long long conversion_duration
Duration of conversion.
double RANSAC_eps
RANSAC epsilon value.
long long Total_time
Total time taken.
long long generatedClusters
Number of clusters generated.
long long yellows
Number of points identified as yellow.
long long blues
Number of points identified as blue.
long long RANSAC_time
Time taken by RANSAC algorithm.
long long ConeDif_time
Time taken by ConeDif algorithm.
long long undefineds
Number of points identified as undefined.