77#include < algorithm>
88#include < chrono>
99#include < ranges>
10- #include < utility>
1110#include < vector>
1211
1312#include < sleipnir/optimization/problem.hpp>
@@ -84,7 +83,7 @@ SwerveTrajectoryGenerator::SwerveTrajectoryGenerator(
8483 _Fy.reserve (moduleCnt);
8584 }
8685
87- dts.reserve (sgmtCnt );
86+ dts.reserve (sampTot );
8887
8988 for (size_t index = 0 ; index < sampTot; ++index) {
9089 x.emplace_back (problem.decision_variable ());
@@ -102,9 +101,7 @@ SwerveTrajectoryGenerator::SwerveTrajectoryGenerator(
102101 Fx.at (index).emplace_back (problem.decision_variable ());
103102 Fy.at (index).emplace_back (problem.decision_variable ());
104103 }
105- }
106104
107- for (size_t sgmtIndex = 0 ; sgmtIndex < sgmtCnt; ++sgmtIndex) {
108105 dts.emplace_back (problem.decision_variable ());
109106 }
110107
@@ -118,7 +115,6 @@ SwerveTrajectoryGenerator::SwerveTrajectoryGenerator(
118115 }
119116
120117 // Minimize total time
121- slp::Variable T_tot = 0 ;
122118 const double maxForce =
123119 path.drivetrain .wheelMaxTorque * 4 / path.drivetrain .wheelRadius ;
124120 const auto maxAccel = maxForce / path.drivetrain .mass ;
@@ -131,21 +127,16 @@ SwerveTrajectoryGenerator::SwerveTrajectoryGenerator(
131127 const auto maxAngVel = maxDrivetrainVelocity / maxWheelPositionRadius;
132128 const auto maxAngAccel = maxAccel / maxWheelPositionRadius;
133129 for (size_t sgmtIndex = 0 ; sgmtIndex < Ns.size (); ++sgmtIndex) {
134- auto & dt = dts.at (sgmtIndex);
135130 auto N_sgmt = Ns.at (sgmtIndex);
136- auto T_sgmt = dt * static_cast < int >(N_sgmt );
137- T_tot += T_sgmt ;
131+ const auto sgmt_start = GetIndex (Ns, sgmtIndex );
132+ const auto sgmt_end = GetIndex (Ns, sgmtIndex + 1 ) ;
138133
139- problem.subject_to (dt >= 0 );
140- problem.subject_to (dt * path.drivetrain .wheelRadius *
141- path.drivetrain .wheelMaxAngularVelocity <=
142- minWidth);
143134 if (N_sgmt == 0 ) {
144- dt.set_value (0 );
135+ for (size_t index = sgmt_start; index < sgmt_end + 1 ; ++index) {
136+ dts.at (index).set_value (0.0 );
137+ }
145138 } else {
146139 // Use initialGuess and Ns to find the dx, dy, dθ between wpts
147- const auto sgmt_start = GetIndex (Ns, sgmtIndex);
148- const auto sgmt_end = GetIndex (Ns, sgmtIndex + 1 );
149140 const auto dx =
150141 initialGuess.x .at (sgmt_end) - initialGuess.x .at (sgmt_start);
151142 const auto dy =
@@ -167,15 +158,19 @@ SwerveTrajectoryGenerator::SwerveTrajectoryGenerator(
167158 CalculateTrapezoidalTime (dist, maxLinearVel, maxAccel);
168159 const double sgmtTime = angularTime + linearTime;
169160
170- dt.set_value (sgmtTime / N_sgmt);
161+ for (size_t index = sgmt_start; index < sgmt_end + 1 ; ++index) {
162+ auto & dt = dts.at (index);
163+ problem.subject_to (dt >= 0 );
164+ problem.subject_to (dt <= 3 );
165+ dt.set_value (sgmtTime / N_sgmt);
166+ }
171167 }
172168 }
173- problem.minimize (std::move (T_tot ));
169+ problem.minimize (std::accumulate (dts. begin (), dts. end (), slp::Variable{ 0.0 } ));
174170
175171 // Apply kinematics constraints
176172 for (size_t wptIndex = 0 ; wptIndex < wptCnt - 1 ; ++wptIndex) {
177173 size_t N_sgmt = Ns.at (wptIndex);
178- auto dt = dts.at (wptIndex);
179174
180175 for (size_t sampleIndex = 0 ; sampleIndex < N_sgmt; ++sampleIndex) {
181176 size_t index = GetIndex (Ns, wptIndex, sampleIndex);
@@ -198,14 +193,20 @@ SwerveTrajectoryGenerator::SwerveTrajectoryGenerator(
198193 auto α_k = α.at (index);
199194 auto α_k_1 = α.at (index + 1 );
200195
196+ auto dt_k = dts.at (index);
197+ if (sampleIndex < N_sgmt - 1 ) {
198+ auto dt_k_1 = dts.at (index + 1 );
199+ problem.subject_to (dt_k_1 == dt_k);
200+ }
201+
201202 // xₖ₊₁ = xₖ + vₖt + 1/2aₖt²
202203 // θₖ₊₁ = θₖ + ωₖt
203204 // vₖ₊₁ = vₖ + aₖt
204205 // ωₖ₊₁ = ωₖ + αₖt
205- problem.subject_to (x_k_1 == x_k + v_k * dt + a_k * 0.5 * dt * dt );
206- problem.subject_to ((θ_k_1 - θ_k) == Rotation2v{ω_k * dt });
207- problem.subject_to (v_k_1 == v_k + a_k * dt );
208- problem.subject_to (ω_k_1 == ω_k + α_k * dt );
206+ problem.subject_to (x_k_1 == x_k + v_k * dt_k + a_k * 0.5 * dt_k * dt_k );
207+ problem.subject_to ((θ_k_1 - θ_k) == Rotation2v{ω_k * dt_k });
208+ problem.subject_to (v_k_1 == v_k + a_k * dt_k );
209+ problem.subject_to (ω_k_1 == ω_k + α_k * dt_k );
209210 }
210211 }
211212
@@ -378,17 +379,6 @@ void SwerveTrajectoryGenerator::ApplyInitialGuess(
378379}
379380
380381SwerveSolution SwerveTrajectoryGenerator::ConstructSwerveSolution () {
381- std::vector<double > dtPerSample;
382- for (size_t sgmtIndex = 0 ; sgmtIndex < Ns.size (); ++sgmtIndex) {
383- auto N = Ns.at (sgmtIndex);
384- auto dt = dts.at (sgmtIndex);
385-
386- double dt_value = dt.value ();
387- for (size_t i = 0 ; i < N; ++i) {
388- dtPerSample.push_back (dt_value);
389- }
390- }
391-
392382 auto getValue = [](auto & var) { return var.value (); };
393383
394384 auto vectorValue = [&](std::vector<slp::Variable>& row) {
@@ -404,7 +394,7 @@ SwerveSolution SwerveTrajectoryGenerator::ConstructSwerveSolution() {
404394 std::ranges::to<std::vector>();
405395 };
406396
407- return SwerveSolution{dtPerSample, vectorValue (x), vectorValue (y),
397+ return SwerveSolution{vectorValue (dts), vectorValue (x), vectorValue (y),
408398 vectorValue (cosθ), vectorValue (sinθ), vectorValue (vx),
409399 vectorValue (vy), vectorValue (ω), vectorValue (ax),
410400 vectorValue (ay), vectorValue (α), matrixValue (Fx),
0 commit comments