@@ -889,6 +889,78 @@ namespace cddp
889889 k_lambda_.back () = V_x;
890890 K_lambda_.back () = V_xx;
891891
892+ if (!has_path_constraints && !has_terminal_ineq && has_terminal_eq)
893+ {
894+ const Eigen::VectorXd h_T =
895+ evaluateTerminalEqualityResidual (context, context.X_ .back ());
896+ const Eigen::MatrixXd H_T =
897+ evaluateTerminalEqualityJacobian (context, context.X_ .back ());
898+
899+ std::vector<Eigen::MatrixXd> Q (horizon + 1 ,
900+ Eigen::MatrixXd::Zero (state_dim, state_dim));
901+ std::vector<Eigen::VectorXd> q (horizon + 1 ,
902+ Eigen::VectorXd::Zero (state_dim));
903+ std::vector<Eigen::MatrixXd> R (horizon,
904+ Eigen::MatrixXd::Zero (control_dim, control_dim));
905+ std::vector<Eigen::VectorXd> r (horizon,
906+ Eigen::VectorXd::Zero (control_dim));
907+ std::vector<Eigen::MatrixXd> M (horizon,
908+ Eigen::MatrixXd::Zero (state_dim, control_dim));
909+ std::vector<Eigen::MatrixXd> A_vec (horizon,
910+ Eigen::MatrixXd::Zero (state_dim, state_dim));
911+ std::vector<Eigen::MatrixXd> B_vec (horizon,
912+ Eigen::MatrixXd::Zero (state_dim, control_dim));
913+ std::vector<Eigen::VectorXd> d_vec (horizon,
914+ Eigen::VectorXd::Zero (state_dim));
915+
916+ Q.back () = V_xx;
917+ q.back () = context.getObjective ().getFinalCostGradient (context.X_ .back ());
918+
919+ for (int t = 0 ; t < horizon; ++t)
920+ {
921+ auto [l_x, l_u] =
922+ context.getObjective ().getRunningCostGradients (context.X_ [t], context.U_ [t], t);
923+ auto [l_xx, l_uu, l_ux] =
924+ context.getObjective ().getRunningCostHessians (context.X_ [t], context.U_ [t], t);
925+
926+ Q[t] = 0.5 * (l_xx + l_xx.transpose ());
927+ q[t] = l_x;
928+ R[t] = 0.5 * (l_uu + l_uu.transpose ());
929+ R[t].diagonal ().array () += context.regularization_ ;
930+ r[t] = l_u;
931+ M[t] = l_ux.transpose ();
932+ A_vec[t] = F_x_[t];
933+ B_vec[t] = F_u_[t];
934+ }
935+
936+ Eigen::VectorXd lambda_total;
937+ Eigen::VectorXd lambda_delta;
938+ if (!solveTerminalEqualityLQR (
939+ Q, q, R, r, M, A_vec, B_vec, d_vec,
940+ Eigen::VectorXd::Zero (state_dim), H_T , -h_T, mu_,
941+ options.ipddp .jacobian_regularization_value ,
942+ options.ipddp .jacobian_regularization_exponent , &Lambda_T_eq_,
943+ K_u_, k_u_, K_lambda_, k_lambda_, lambda_total, lambda_delta))
944+ {
945+ return false ;
946+ }
947+
948+ dLambda_T_eq_ = lambda_delta;
949+ dV_ = Eigen::Vector2d::Zero ();
950+ inf_du = lambda_delta.lpNorm <Eigen::Infinity>();
951+ for (int t = 0 ; t < horizon; ++t)
952+ {
953+ inf_du = std::max (inf_du, k_u_[t].lpNorm <Eigen::Infinity>());
954+ step_norm = std::max (step_norm, k_u_[t].lpNorm <Eigen::Infinity>());
955+ }
956+
957+ context.inf_du_ = inf_du;
958+ context.step_norm_ = step_norm;
959+ context.inf_pr_ = h_T.lpNorm <Eigen::Infinity>();
960+ context.inf_comp_ = 0.0 ;
961+ return true ;
962+ }
963+
892964 if (!has_path_constraints && !has_terminal_ineq && !has_terminal_eq)
893965 {
894966 for (int t = horizon - 1 ; t >= 0 ; --t)
@@ -1388,7 +1460,7 @@ namespace cddp
13881460 }
13891461
13901462 bool filter_acceptance = false ;
1391- if (constraint_set.empty () && !has_terminal_ineq)
1463+ if (constraint_set.empty () && !has_terminal_ineq && !has_terminal_eq )
13921464 {
13931465 double dJ = context.cost_ - cost_new;
13941466 double expected = -alpha_pr * (dV_ (0 ) + 0.5 * alpha_pr * dV_ (1 ));
@@ -2033,6 +2105,10 @@ namespace cddp
20332105 has_terminal_eq ? &h_T : nullptr ),
20342106 std::max (context.getOptions ().ipddp .theta_0_floor , 1e-8 ));
20352107 filter_.clear ();
2108+ if (has_terminal_ineq || has_terminal_eq)
2109+ {
2110+ acceptFilterEntry (phi_, theta_);
2111+ }
20362112 }
20372113
20382114 void IPDDPSolver::resetFilter (CDDP &context) { resetBarrierFilter (context); }
@@ -2136,11 +2212,16 @@ namespace cddp
21362212 if (reset_filter)
21372213 {
21382214 filter_.clear ();
2215+ if (getTerminalEqualityDim (context) > 0 ||
2216+ !getTerminalInequalityLayout (context).empty ())
2217+ {
2218+ acceptFilterEntry (phi_, theta_);
2219+ }
21392220 }
21402221 else
21412222 {
21422223 acceptFilterEntry (phi_, theta_);
2143- if (static_cast <int >(filter_.size ()) > 5 )
2224+ if (static_cast <int >(filter_.size ()) > options. ipddp . max_filter_size )
21442225 {
21452226 detail::pruneFilterToBestPoints (filter_);
21462227 }
@@ -2221,7 +2302,16 @@ namespace cddp
22212302 double IPDDPSolver::computeMaxConstraintViolation (const CDDP &context) const
22222303 {
22232304 (void )context;
2224- return detail::computeMaxConstraintViolation (G_ );
2305+ double max_violation = detail::computeMaxConstraintViolation (G_ );
2306+ for (const auto &entry : G_T_ )
2307+ {
2308+ if (entry.second .size () == 0 )
2309+ {
2310+ continue ;
2311+ }
2312+ max_violation = std::max (max_violation, entry.second .maxCoeff ());
2313+ }
2314+ return max_violation;
22252315 }
22262316
22272317 double IPDDPSolver::computeScaledDualInfeasibility (const CDDP &context) const
0 commit comments