20
20
#include " interpolation/linear_interpolation.hpp"
21
21
#include " rclcpp/rclcpp.hpp"
22
22
23
+ #include < Eigen/Sparse>
24
+
23
25
#include < algorithm>
24
26
#include < limits>
25
27
@@ -576,22 +578,47 @@ std::pair<bool, VectorXd> MPC::executeOptimization(
576
578
577
579
const int DIM_U_N = m_param.prediction_horizon * m_vehicle_model_ptr->getDimU ();
578
580
581
+ Eigen::SparseMatrix<double > Cex_sparse = m.Cex .sparseView ();
582
+ Eigen::SparseMatrix<double > Bex_sparse = m.Bex .sparseView ();
583
+ Eigen::SparseMatrix<double > Qex_sparse = m.Qex .sparseView ();
584
+ Eigen::SparseMatrix<double > R1ex_sparse = m.R1ex .sparseView ();
585
+ Eigen::SparseMatrix<double > R2ex_sparse = m.R2ex .sparseView ();
586
+
579
587
// cost function: 1/2 * Uex' * H * Uex + f' * Uex, H = B' * C' * Q * C * B + R
580
- const MatrixXd CB = m.Cex * m.Bex ;
581
- const MatrixXd QCB = m.Qex * CB;
582
- // MatrixXd H = CB.transpose() * QCB + m.R1ex + m.R2ex; // This calculation is heavy. looking for
583
- // a good way. //NOLINT
584
- MatrixXd H = MatrixXd::Zero (DIM_U_N, DIM_U_N);
585
- H.triangularView <Eigen::Upper>() = CB.transpose () * QCB;
586
- H.triangularView <Eigen::Upper>() += m.R1ex + m.R2ex ;
587
- H.triangularView <Eigen::Lower>() = H.transpose ();
588
- MatrixXd f = (m.Cex * (m.Aex * x0 + m.Wex )).transpose () * QCB - m.Uref_ex .transpose () * m.R1ex ;
588
+ Eigen::SparseMatrix<double > CB_sparse (DIM_U_N, DIM_U_N);
589
+ CB_sparse = Cex_sparse * Bex_sparse;
590
+
591
+ Eigen::SparseMatrix<double > QCB_sparse (DIM_U_N, DIM_U_N);
592
+ QCB_sparse = Qex_sparse * CB_sparse;
593
+
594
+ Eigen::SparseMatrix<double > H_sparse (DIM_U_N, DIM_U_N);
595
+ {
596
+ Eigen::SparseMatrix<double > temp_sparse (DIM_U_N, DIM_U_N);
597
+ temp_sparse = CB_sparse.transpose () * QCB_sparse;
598
+
599
+ H_sparse = temp_sparse + R1ex_sparse + R2ex_sparse;
600
+ }
601
+
602
+ VectorXd f = VectorXd::Zero (DIM_U_N);
603
+ {
604
+ VectorXd CAW = VectorXd::Zero (Cex_sparse.rows ());
605
+ CAW = Cex_sparse * (m.Aex * x0 + m.Wex );
606
+
607
+ f = QCB_sparse.transpose () * CAW;
608
+ f -= m.Uref_ex .transpose () * R1ex_sparse;
609
+ }
610
+
589
611
addSteerWeightF (prediction_dt, f);
590
612
591
- MatrixXd A = MatrixXd::Identity (DIM_U_N, DIM_U_N);
592
- for (int i = 1 ; i < DIM_U_N; i++) {
593
- A (i, i - 1 ) = -1.0 ;
613
+ Eigen::SparseMatrix<double > A_sparse (DIM_U_N, DIM_U_N);
614
+ std::vector<Eigen::Triplet<double >> triplets;
615
+ for (int i = 0 ; i < DIM_U_N; ++i) {
616
+ triplets.emplace_back (i, i, 1.0 );
617
+ if (i > 0 ) {
618
+ triplets.emplace_back (i, i - 1 , -1.0 );
619
+ }
594
620
}
621
+ A_sparse.setFromTriplets (triplets.begin (), triplets.end ());
595
622
596
623
// steering angle limit
597
624
VectorXd lb = VectorXd::Constant (DIM_U_N, -m_steer_lim); // min steering angle
@@ -605,7 +632,8 @@ std::pair<bool, VectorXd> MPC::executeOptimization(
605
632
lbA (0 ) = m_raw_steer_cmd_prev - steer_rate_limits (0 ) * m_ctrl_period;
606
633
607
634
auto t_start = std::chrono::system_clock::now ();
608
- bool solve_result = m_qpsolver_ptr->solve (H, f.transpose (), A, lb, ub, lbA, ubA, Uex);
635
+ bool solve_result =
636
+ m_qpsolver_ptr->solve (H_sparse, f.transpose (), A_sparse, lb, ub, lbA, ubA, Uex);
609
637
auto t_end = std::chrono::system_clock::now ();
610
638
if (!solve_result) {
611
639
warn_throttle (" qp solver error" );
@@ -667,16 +695,16 @@ void MPC::addSteerWeightR(const double prediction_dt, MatrixXd & R) const
667
695
}
668
696
}
669
697
670
- void MPC::addSteerWeightF (const double prediction_dt, MatrixXd & f) const
698
+ void MPC::addSteerWeightF (const double prediction_dt, VectorXd & f) const
671
699
{
672
- if (f.rows () < 2 ) {
700
+ if (f.size () < 2 ) {
673
701
return ;
674
702
}
675
703
676
704
const double DT = prediction_dt;
677
705
678
706
// steer rate for i = 0
679
- f (0 , 0 ) += -2.0 * m_param.nominal_weight .steer_rate / (std::pow (DT, 2 )) * 0.5 ;
707
+ f (0 ) += -2.0 * m_param.nominal_weight .steer_rate / (std::pow (DT, 2 )) * 0.5 ;
680
708
681
709
// const double steer_acc_r = m_param.weight_steer_acc / std::pow(DT, 4);
682
710
const double steer_acc_r_cp1 =
@@ -686,11 +714,11 @@ void MPC::addSteerWeightF(const double prediction_dt, MatrixXd & f) const
686
714
const double steer_acc_r_cp4 = m_param.nominal_weight .steer_acc / std::pow (m_ctrl_period, 4 );
687
715
688
716
// steer acc i = 0
689
- f (0 , 0 ) += ((-2.0 * m_raw_steer_cmd_prev + m_raw_steer_cmd_pprev) * steer_acc_r_cp4) * 0.5 ;
717
+ f (0 ) += ((-2.0 * m_raw_steer_cmd_prev + m_raw_steer_cmd_pprev) * steer_acc_r_cp4) * 0.5 ;
690
718
691
719
// steer acc for i = 1
692
- f (0 , 0 ) += (-2.0 * m_raw_steer_cmd_prev * (steer_acc_r_cp1 + steer_acc_r_cp2)) * 0.5 ;
693
- f (0 , 1 ) += (2.0 * m_raw_steer_cmd_prev * steer_acc_r_cp1) * 0.5 ;
720
+ f (0 ) += (-2.0 * m_raw_steer_cmd_prev * (steer_acc_r_cp1 + steer_acc_r_cp2)) * 0.5 ;
721
+ f (1 ) += (2.0 * m_raw_steer_cmd_prev * steer_acc_r_cp1) * 0.5 ;
694
722
}
695
723
696
724
double MPC::getPredictionDeltaTime (
0 commit comments