12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
+ #include " ament_index_cpp/get_package_share_directory.hpp"
15
16
#include " gtest/gtest.h"
16
17
#include " mpc_lateral_controller/mpc.hpp"
17
18
#include " mpc_lateral_controller/qp_solver/qp_solver_osqp.hpp"
@@ -49,6 +50,18 @@ using geometry_msgs::msg::Pose;
49
50
using geometry_msgs::msg::PoseStamped;
50
51
using tier4_debug_msgs::msg::Float32MultiArrayStamped;
51
52
53
+ rclcpp::NodeOptions makeNodeOptions ()
54
+ {
55
+ // Pass default parameter file to the node
56
+ const auto share_dir = ament_index_cpp::get_package_share_directory (" mpc_lateral_controller" );
57
+ rclcpp::NodeOptions node_options;
58
+ node_options.arguments (
59
+ {" --ros-args" , " --params-file" , share_dir + " /param/lateral_controller_defaults.param.yaml" ,
60
+ " --params-file" , share_dir + " /test/test_vehicle_info.param.yaml" });
61
+
62
+ return node_options;
63
+ }
64
+
52
65
TrajectoryPoint makePoint (const double x, const double y, const float vx)
53
66
{
54
67
TrajectoryPoint p;
@@ -77,69 +90,12 @@ class MPCTest : public ::testing::Test
77
90
double default_velocity = 1.0 ;
78
91
rclcpp::Logger logger = rclcpp::get_logger(" mpc_test_logger" );
79
92
80
- // Vehicle model parameters
81
- double wheelbase = 2.7 ;
82
- double steer_limit = 1.0 ;
83
- double steer_tau = 0.1 ;
84
- double mass_fl = 600.0 ;
85
- double mass_fr = 600.0 ;
86
- double mass_rl = 600.0 ;
87
- double mass_rr = 600.0 ;
88
- double cf = 155494.663 ;
89
- double cr = 155494.663 ;
90
-
91
- // Filters parameter
92
- double steering_lpf_cutoff_hz = 3.0 ;
93
- double error_deriv_lpf_cutoff_hz = 5.0 ;
94
-
95
- // Test Parameters
96
- double admissible_position_error = 5.0 ;
97
- double admissible_yaw_error_rad = M_PI_2;
98
- double steer_lim = 0.610865 ; // 35 degrees
99
- double steer_rate_lim = 2.61799 ; // 150 degrees
100
93
double ctrl_period = 0.03 ;
101
94
102
- bool use_steer_prediction = true ;
103
-
104
95
TrajectoryFilteringParam trajectory_param;
105
96
106
97
void initParam ()
107
98
{
108
- param.prediction_horizon = 50 ;
109
- param.prediction_dt = 0.1 ;
110
- param.zero_ff_steer_deg = 0.5 ;
111
- param.input_delay = 0.0 ;
112
- param.acceleration_limit = 2.0 ;
113
- param.velocity_time_constant = 0.3 ;
114
- param.min_prediction_length = 5.0 ;
115
- param.steer_tau = 0.1 ;
116
- param.nominal_weight .lat_error = 1.0 ;
117
- param.nominal_weight .heading_error = 1.0 ;
118
- param.nominal_weight .heading_error_squared_vel = 1.0 ;
119
- param.nominal_weight .terminal_lat_error = 1.0 ;
120
- param.nominal_weight .terminal_heading_error = 0.1 ;
121
- param.low_curvature_weight .lat_error = 0.1 ;
122
- param.low_curvature_weight .heading_error = 0.0 ;
123
- param.low_curvature_weight .heading_error_squared_vel = 0.3 ;
124
- param.nominal_weight .steering_input = 1.0 ;
125
- param.nominal_weight .steering_input_squared_vel = 0.25 ;
126
- param.nominal_weight .lat_jerk = 0.0 ;
127
- param.nominal_weight .steer_rate = 0.0 ;
128
- param.nominal_weight .steer_acc = 0.000001 ;
129
- param.low_curvature_weight .steering_input = 1.0 ;
130
- param.low_curvature_weight .steering_input_squared_vel = 0.25 ;
131
- param.low_curvature_weight .lat_jerk = 0.0 ;
132
- param.low_curvature_weight .steer_rate = 0.0 ;
133
- param.low_curvature_weight .steer_acc = 0.000001 ;
134
- param.low_curvature_thresh_curvature = 0.0 ;
135
-
136
- trajectory_param.traj_resample_dist = 0.1 ;
137
- trajectory_param.path_filter_moving_ave_num = 35 ;
138
- trajectory_param.curvature_smoothing_num_traj = 1 ;
139
- trajectory_param.curvature_smoothing_num_ref_steer = 35 ;
140
- trajectory_param.enable_path_smoothing = true ;
141
- trajectory_param.extend_trajectory_for_end_yaw_control = true ;
142
-
143
99
dummy_straight_trajectory.points .push_back (makePoint (0.0 , 0.0 , 1 .0f ));
144
100
dummy_straight_trajectory.points .push_back (makePoint (1.0 , 0.0 , 1 .0f ));
145
101
dummy_straight_trajectory.points .push_back (makePoint (2.0 , 0.0 , 1 .0f ));
@@ -158,18 +114,7 @@ class MPCTest : public ::testing::Test
158
114
159
115
void initializeMPC (mpc_lateral_controller::MPC & mpc)
160
116
{
161
- mpc.m_param = param;
162
- mpc.m_admissible_position_error = admissible_position_error;
163
- mpc.m_admissible_yaw_error_rad = admissible_yaw_error_rad;
164
- mpc.m_steer_lim = steer_lim;
165
- mpc.m_steer_rate_lim_map_by_curvature .emplace_back (0.0 , steer_rate_lim);
166
- mpc.m_steer_rate_lim_map_by_velocity .emplace_back (0.0 , steer_rate_lim);
167
117
mpc.m_ctrl_period = ctrl_period;
168
- mpc.m_use_steer_prediction = use_steer_prediction;
169
-
170
- mpc.initializeLowPassFilters (steering_lpf_cutoff_hz, error_deriv_lpf_cutoff_hz);
171
- mpc.initializeSteeringPredictor ();
172
-
173
118
// Init trajectory
174
119
const auto current_kinematics =
175
120
makeOdometry (dummy_straight_trajectory.points .front ().pose , 0.0 );
@@ -188,14 +133,10 @@ class MPCTest : public ::testing::Test
188
133
/* cppcheck-suppress syntaxError */
189
134
TEST_F (MPCTest, InitializeAndCalculate)
190
135
{
191
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
136
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
192
137
auto mpc = std::make_unique<MPC>(node);
193
138
EXPECT_FALSE (mpc->hasVehicleModel ());
194
139
EXPECT_FALSE (mpc->hasQPSolver ());
195
-
196
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
197
- std::make_shared<KinematicsBicycleModel>(wheelbase, steer_limit, steer_tau);
198
- mpc->setVehicleModel (vehicle_model_ptr);
199
140
ASSERT_TRUE (mpc->hasVehicleModel ());
200
141
201
142
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverEigenLeastSquareLLT>();
@@ -217,14 +158,11 @@ TEST_F(MPCTest, InitializeAndCalculate)
217
158
218
159
TEST_F (MPCTest, InitializeAndCalculateRightTurn)
219
160
{
220
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
161
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
221
162
auto mpc = std::make_unique<MPC>(node);
222
163
EXPECT_FALSE (mpc->hasVehicleModel ());
223
164
EXPECT_FALSE (mpc->hasQPSolver ());
224
165
225
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
226
- std::make_shared<KinematicsBicycleModel>(wheelbase, steer_limit, steer_tau);
227
- mpc->setVehicleModel (vehicle_model_ptr);
228
166
ASSERT_TRUE (mpc->hasVehicleModel ());
229
167
230
168
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverEigenLeastSquareLLT>();
@@ -249,15 +187,12 @@ TEST_F(MPCTest, InitializeAndCalculateRightTurn)
249
187
250
188
TEST_F (MPCTest, OsqpCalculate)
251
189
{
252
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
190
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
253
191
auto mpc = std::make_unique<MPC>(node);
254
192
initializeMPC (*mpc);
255
193
const auto current_kinematics = makeOdometry (dummy_straight_trajectory.points .front ().pose , 0.0 );
256
194
mpc->setReferenceTrajectory (dummy_straight_trajectory, trajectory_param, current_kinematics);
257
195
258
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
259
- std::make_shared<KinematicsBicycleModel>(wheelbase, steer_limit, steer_tau);
260
- mpc->setVehicleModel (vehicle_model_ptr);
261
196
ASSERT_TRUE (mpc->hasVehicleModel ());
262
197
263
198
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverOSQP>(logger);
@@ -276,16 +211,12 @@ TEST_F(MPCTest, OsqpCalculate)
276
211
277
212
TEST_F (MPCTest, OsqpCalculateRightTurn)
278
213
{
279
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
214
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
280
215
auto mpc = std::make_unique<MPC>(node);
281
216
initializeMPC (*mpc);
282
217
const auto current_kinematics =
283
218
makeOdometry (dummy_right_turn_trajectory.points .front ().pose , 0.0 );
284
219
mpc->setReferenceTrajectory (dummy_right_turn_trajectory, trajectory_param, current_kinematics);
285
-
286
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
287
- std::make_shared<KinematicsBicycleModel>(wheelbase, steer_limit, steer_tau);
288
- mpc->setVehicleModel (vehicle_model_ptr);
289
220
ASSERT_TRUE (mpc->hasVehicleModel ());
290
221
291
222
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverOSQP>(logger);
@@ -304,21 +235,15 @@ TEST_F(MPCTest, OsqpCalculateRightTurn)
304
235
305
236
TEST_F (MPCTest, KinematicsNoDelayCalculate)
306
237
{
307
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
238
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
308
239
auto mpc = std::make_unique<MPC>(node);
309
240
initializeMPC (*mpc);
310
-
311
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
312
- std::make_shared<KinematicsBicycleModelNoDelay>(wheelbase, steer_limit);
313
- mpc->setVehicleModel (vehicle_model_ptr);
314
241
ASSERT_TRUE (mpc->hasVehicleModel ());
315
242
316
243
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverEigenLeastSquareLLT>();
317
244
mpc->setQPSolver (qpsolver_ptr);
318
245
ASSERT_TRUE (mpc->hasQPSolver ());
319
246
320
- // Init filters
321
- mpc->initializeLowPassFilters (steering_lpf_cutoff_hz, error_deriv_lpf_cutoff_hz);
322
247
// Init trajectory
323
248
const auto current_kinematics = makeOdometry (dummy_straight_trajectory.points .front ().pose , 0.0 );
324
249
mpc->setReferenceTrajectory (dummy_straight_trajectory, trajectory_param, current_kinematics);
@@ -334,25 +259,18 @@ TEST_F(MPCTest, KinematicsNoDelayCalculate)
334
259
335
260
TEST_F (MPCTest, KinematicsNoDelayCalculateRightTurn)
336
261
{
337
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
262
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
338
263
auto mpc = std::make_unique<MPC>(node);
339
264
initializeMPC (*mpc);
340
265
const auto current_kinematics =
341
266
makeOdometry (dummy_right_turn_trajectory.points .front ().pose , 0.0 );
342
267
mpc->setReferenceTrajectory (dummy_right_turn_trajectory, trajectory_param, current_kinematics);
343
-
344
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
345
- std::make_shared<KinematicsBicycleModelNoDelay>(wheelbase, steer_limit);
346
- mpc->setVehicleModel (vehicle_model_ptr);
347
268
ASSERT_TRUE (mpc->hasVehicleModel ());
348
269
349
270
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverEigenLeastSquareLLT>();
350
271
mpc->setQPSolver (qpsolver_ptr);
351
272
ASSERT_TRUE (mpc->hasQPSolver ());
352
273
353
- // Init filters
354
- mpc->initializeLowPassFilters (steering_lpf_cutoff_hz, error_deriv_lpf_cutoff_hz);
355
-
356
274
// Calculate MPC
357
275
AckermannLateralCommand ctrl_cmd;
358
276
Trajectory pred_traj;
@@ -365,13 +283,10 @@ TEST_F(MPCTest, KinematicsNoDelayCalculateRightTurn)
365
283
366
284
TEST_F (MPCTest, DynamicCalculate)
367
285
{
368
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
286
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
369
287
auto mpc = std::make_unique<MPC>(node);
370
288
initializeMPC (*mpc);
371
289
372
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
373
- std::make_shared<DynamicsBicycleModel>(wheelbase, mass_fl, mass_fr, mass_rl, mass_rr, cf, cr);
374
- mpc->setVehicleModel (vehicle_model_ptr);
375
290
ASSERT_TRUE (mpc->hasVehicleModel ());
376
291
377
292
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverEigenLeastSquareLLT>();
@@ -390,11 +305,8 @@ TEST_F(MPCTest, DynamicCalculate)
390
305
391
306
TEST_F (MPCTest, MultiSolveWithBuffer)
392
307
{
393
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
308
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
394
309
auto mpc = std::make_unique<MPC>(node);
395
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
396
- std::make_shared<KinematicsBicycleModel>(wheelbase, steer_limit, steer_tau);
397
- mpc->setVehicleModel (vehicle_model_ptr);
398
310
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverEigenLeastSquareLLT>();
399
311
mpc->setQPSolver (qpsolver_ptr);
400
312
@@ -428,11 +340,8 @@ TEST_F(MPCTest, MultiSolveWithBuffer)
428
340
429
341
TEST_F (MPCTest, FailureCases)
430
342
{
431
- auto node = rclcpp::Node (" mpc_test_node" , rclcpp::NodeOptions{} );
343
+ auto node = rclcpp::Node (" mpc_test_node" , makeNodeOptions () );
432
344
auto mpc = std::make_unique<MPC>(node);
433
- std::shared_ptr<VehicleModelInterface> vehicle_model_ptr =
434
- std::make_shared<KinematicsBicycleModel>(wheelbase, steer_limit, steer_tau);
435
- mpc->setVehicleModel (vehicle_model_ptr);
436
345
std::shared_ptr<QPSolverInterface> qpsolver_ptr = std::make_shared<QPSolverEigenLeastSquareLLT>();
437
346
mpc->setQPSolver (qpsolver_ptr);
438
347
@@ -441,6 +350,7 @@ TEST_F(MPCTest, FailureCases)
441
350
442
351
// Calculate MPC with a pose too far from the trajectory
443
352
Pose pose_far;
353
+ constexpr double admissible_position_error = 5.0 ;
444
354
pose_far.position .x = pose_zero.position .x - admissible_position_error - 1.0 ;
445
355
pose_far.position .y = pose_zero.position .y - admissible_position_error - 1.0 ;
446
356
AckermannLateralCommand ctrl_cmd;
0 commit comments