23#include "opencv2/opencv.hpp"
37bool TrajectoryImitationLibtorchInference::LoadCNNModel() {
39 torch::Tensor input_feature_tensor = torch::zeros({1, 12, 200, 200});
40 std::vector<torch::jit::IValue> torch_inputs;
41 torch_inputs.push_back(input_feature_tensor.to(device_));
43 auto torch_output_tensor =
44 model_.forward(torch_inputs).toTensor().to(torch::kCPU);
45 }
catch (
const c10::Error& e) {
46 AERROR <<
"Fail to do initial inference on CNN Model";
52bool TrajectoryImitationLibtorchInference::LoadCNNLSTMModel() {
54 torch::Tensor input_feature_tensor = torch::zeros({1, 12, 200, 200});
55 torch::Tensor current_v = torch::zeros({1, 1});
56 std::vector<torch::jit::IValue> torch_inputs;
57 torch_inputs.push_back(
58 c10::ivalue::Tuple::create({std::move(input_feature_tensor.to(device_)),
59 std::move(current_v.to(device_))}));
61 auto torch_output_tensor =
62 model_.forward(torch_inputs).toTensor().to(torch::kCPU);
63 }
catch (
const c10::Error& e) {
64 AERROR <<
"Fail to do initial inference on HISTORY_UNCONDITIONED_CNN_LSTM "
73 ADEBUG <<
"CUDA is available";
74 device_ = torch::Device(torch::kCUDA);
77 }
catch (
const c10::Error& e) {
78 AERROR <<
"Failed to load model on to device";
85 torch::set_num_threads(1);
88 if (!LoadCNNModel()) {
94 if (!LoadCNNLSTMModel()) {
100 AERROR <<
"Configured model type not defined and implemented";
107void TrajectoryImitationLibtorchInference::output_postprocessing(
108 const at::Tensor& torch_output_tensor,
110 const int past_points_size = learning_data_frame->adc_trajectory_point_size();
111 const auto& cur_traj_point =
114 const auto& cur_path_point = cur_traj_point.trajectory_point().path_point();
115 const double cur_x = cur_path_point.x();
116 const double cur_y = cur_path_point.y();
117 const double cur_heading = cur_path_point.theta();
118 ADEBUG <<
"cur_x[" << cur_x <<
"], cur_y[" << cur_y <<
"], cur_heading["
119 << cur_heading <<
"], cur_v[" << cur_traj_point.trajectory_point().v()
122 learning_data_frame->mutable_output()->clear_adc_future_trajectory_point();
124 auto torch_output = torch_output_tensor.accessor<float, 3>();
125 for (
int i = 0; i < torch_output_tensor.size(1); ++i) {
126 const double dx =
static_cast<double>(torch_output[0][i][0]);
127 const double dy =
static_cast<double>(torch_output[0][i][1]);
128 const double dtheta =
static_cast<double>(torch_output[0][i][2]);
129 const double v =
static_cast<double>(torch_output[0][i][3]);
130 ADEBUG <<
"dx[" << dx <<
"], dy[" << dy <<
"], dtheta[" << dtheta <<
"], v["
132 const double time_sec = cur_time_sec + delta_t * (i + 1);
135 const double x = cur_x + rotated_offset.
x();
136 const double y = cur_y + rotated_offset.
y();
137 const double heading =
140 auto* traj_point = learning_data_frame->mutable_output()
141 ->add_adc_future_trajectory_point();
142 traj_point->set_timestamp_sec(time_sec);
143 traj_point->mutable_trajectory_point()->mutable_path_point()->set_x(x);
144 traj_point->mutable_trajectory_point()->mutable_path_point()->set_y(y);
145 traj_point->mutable_trajectory_point()->mutable_path_point()->set_theta(
147 traj_point->mutable_trajectory_point()->set_v(v);
148 traj_point->mutable_trajectory_point()->set_relative_time(delta_t *
153bool TrajectoryImitationLibtorchInference::DoCNNMODELInference(
154 LearningDataFrame*
const learning_data_frame) {
155 const int past_points_size = learning_data_frame->adc_trajectory_point_size();
156 if (past_points_size == 0) {
157 AERROR <<
"No current trajectory point status";
161 auto input_renderering_start_time = std::chrono::system_clock::now();
163 cv::Mat input_feature;
164 if (!BirdviewImgFeatureRenderer::Instance()->RenderMultiChannelEnv(
165 *learning_data_frame, &input_feature)) {
166 AERROR <<
"Render multi-channel input image failed";
170 auto input_renderering_end_time = std::chrono::system_clock::now();
171 std::chrono::duration<double> rendering_diff =
172 input_renderering_end_time - input_renderering_start_time;
173 ADEBUG <<
"trajectory imitation model input renderer used time: "
174 << rendering_diff.count() * 1000 <<
" ms.";
176 auto input_preprocessing_start_time = std::chrono::system_clock::now();
178 cv::Mat input_feature_float;
179 input_feature.convertTo(input_feature_float, CV_32F, 1.0 / 255);
180 torch::Tensor input_feature_tensor =
181 torch::from_blob(input_feature_float.data,
182 {1, input_feature_float.rows, input_feature_float.cols,
183 input_feature_float.channels()});
184 input_feature_tensor = input_feature_tensor.permute({0, 3, 1, 2});
185 for (
int i = 0; i < input_feature_float.channels(); ++i) {
186 input_feature_tensor[0][i] = input_feature_tensor[0][i].sub(0.5).div(0.5);
189 auto input_preprocessing_end_time = std::chrono::system_clock::now();
190 std::chrono::duration<double> preprocessing_diff =
191 input_preprocessing_end_time - input_preprocessing_start_time;
192 ADEBUG <<
"trajectory imitation model input preprocessing used time: "
193 << preprocessing_diff.count() * 1000 <<
" ms.";
195 auto inference_start_time = std::chrono::system_clock::now();
197 std::vector<torch::jit::IValue> torch_inputs;
198 torch_inputs.push_back(input_feature_tensor.to(device_));
199 at::Tensor torch_output_tensor =
200 model_.forward(torch_inputs).toTensor().to(torch::kCPU);
202 auto inference_end_time = std::chrono::system_clock::now();
203 std::chrono::duration<double> inference_diff =
204 inference_end_time - inference_start_time;
205 ADEBUG <<
"trajectory imitation model inference used time: "
206 << inference_diff.count() * 1000 <<
" ms.";
208 output_postprocessing(torch_output_tensor, learning_data_frame);
213bool TrajectoryImitationLibtorchInference::DoCNNLSTMMODELInference(
214 LearningDataFrame*
const learning_data_frame) {
215 const int past_points_size = learning_data_frame->adc_trajectory_point_size();
216 if (past_points_size == 0) {
217 AERROR <<
"No current trajectory point status";
221 auto input_renderering_start_time = std::chrono::system_clock::now();
223 cv::Mat input_feature;
224 if (!BirdviewImgFeatureRenderer::Instance()->RenderMultiChannelEnv(
225 *learning_data_frame, &input_feature)) {
226 AERROR <<
"Render multi-channel input image failed";
230 auto input_renderering_end_time = std::chrono::system_clock::now();
231 std::chrono::duration<double> rendering_diff =
232 input_renderering_end_time - input_renderering_start_time;
233 ADEBUG <<
"trajectory imitation model input renderer used time: "
234 << rendering_diff.count() * 1000 <<
" ms.";
236 auto input_preprocessing_start_time = std::chrono::system_clock::now();
238 cv::Mat input_feature_float;
239 input_feature.convertTo(input_feature_float, CV_32F, 1.0 / 255);
240 torch::Tensor input_feature_tensor =
241 torch::from_blob(input_feature_float.data,
242 {1, input_feature_float.rows, input_feature_float.cols,
243 input_feature_float.channels()});
244 input_feature_tensor = input_feature_tensor.permute({0, 3, 1, 2});
245 for (
int i = 0; i < input_feature_float.channels(); ++i) {
246 input_feature_tensor[0][i] = input_feature_tensor[0][i].sub(0.5).div(0.5);
249 const auto& current_traj_point =
251 ->adc_trajectory_point(
252 learning_data_frame->adc_trajectory_point_size() - 1)
255 torch::Tensor current_v_tensor = torch::zeros({1, 1});
256 const double current_v = current_traj_point.v();
257 current_v_tensor[0][0] = current_v;
259 auto input_preprocessing_end_time = std::chrono::system_clock::now();
260 std::chrono::duration<double> preprocessing_diff =
261 input_preprocessing_end_time - input_preprocessing_start_time;
262 ADEBUG <<
"trajectory imitation model input preprocessing used time: "
263 << preprocessing_diff.count() * 1000 <<
" ms.";
265 auto inference_start_time = std::chrono::system_clock::now();
267 std::vector<torch::jit::IValue> torch_inputs;
268 torch_inputs.push_back(
269 c10::ivalue::Tuple::create({std::move(input_feature_tensor.to(device_)),
270 std::move(current_v_tensor.to(device_))}));
271 at::Tensor torch_output_tensor =
272 model_.forward(torch_inputs).toTensor().to(torch::kCPU);
274 auto inference_end_time = std::chrono::system_clock::now();
275 std::chrono::duration<double> inference_diff =
276 inference_end_time - inference_start_time;
277 ADEBUG <<
"trajectory imitation model inference used time: "
278 << inference_diff.count() * 1000 <<
" ms.";
280 output_postprocessing(torch_output_tensor, learning_data_frame);
289 if (!DoCNNMODELInference(learning_data_frame)) {
295 if (!DoCNNLSTMMODELInference(learning_data_frame)) {
301 AERROR <<
"Configured model type not defined and implemented";
Define the birdview img feature renderer class
Implements a class of 2-dimensional vectors.
double y() const
Getter for y component
Vec2d rotate(const double angle) const
rotate the vector by angle.
double x() const
Getter for x component
LearningModelInferenceTaskConfig config_
bool LoadModel() override
load a learned model
TrajectoryImitationLibtorchInference(const LearningModelInferenceTaskConfig &config)
Constructor
bool DoInference(LearningDataFrame *const learning_data_frame) override
inference a learned model
Planning module main class.
Math-related util functions.
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
optional double timestamp_sec
repeated ADCTrajectoryPoint adc_trajectory_point
optional string cpu_model_file
optional string gpu_model_file
optional double trajectory_delta_t
optional ModelType model_type
Define the trajectory_imitation_libtorch_inference class