@@ -13,22 +13,17 @@ Car::Car(double timestep, double wheelbase, std::string integration_type)
1313
1414Eigen::VectorXd Car::getDiscreteDynamics (
1515 const Eigen::VectorXd& state, const Eigen::VectorXd& control, double time) const {
16-
17- // Extract states
1816 const double x = state (STATE_X); // x position
1917 const double y = state (STATE_Y); // y position
2018 const double theta = state (STATE_THETA); // car angle
2119 const double v = state (STATE_V); // velocity
2220
23- // Extract controls
2421 const double delta = control (CONTROL_DELTA); // steering angle
2522 const double a = control (CONTROL_A); // acceleration
2623
27- // Constants
2824 const double d = wheelbase_; // distance between back and front axles
2925 const double h = timestep_; // timestep
3026
31- // Compute unit vector in car direction
3227 const double cos_theta = std::cos (theta);
3328 const double sin_theta = std::sin (theta);
3429 Eigen::Vector2d z (cos_theta, sin_theta);
@@ -45,40 +40,30 @@ Eigen::VectorXd Car::getDiscreteDynamics(
4540 // dtheta = asin(sin(w)*f/d)
4641 const double dtheta = std::asin (std::sin (delta) * f / d);
4742
48- // Compute state change
4943 Eigen::VectorXd dy = Eigen::VectorXd::Zero (STATE_DIM);
5044 dy (STATE_X) = b * cos_theta;
5145 dy (STATE_Y) = b * sin_theta;
5246 dy (STATE_THETA) = dtheta;
5347 dy (STATE_V) = h * a;
5448
55- // Return next state
5649 return state + dy;
5750}
5851
5952Eigen::MatrixXd Car::getStateJacobian (
6053 const Eigen::VectorXd& state, const Eigen::VectorXd& control, double time) const {
61-
62- // Convert inputs to autodiff types
6354 VectorXdual2nd state_dual = state.cast <autodiff::dual2nd>();
6455 VectorXdual2nd control_dual = control.cast <autodiff::dual2nd>();
65-
66- // Initialize Jacobian
6756 Eigen::MatrixXd J = Eigen::MatrixXd::Zero (STATE_DIM, STATE_DIM);
6857
69- // Calculate Jacobian using autodiff
7058 for (int i = 0 ; i < STATE_DIM; ++i) {
71- // Create a lambda that returns the i-th component of the dynamics
7259 auto dynamics_i = [this , i, &control_dual, time](const VectorXdual2nd& x) -> autodiff::dual2nd {
7360 VectorXdual2nd dynamics = this ->getDiscreteDynamicsAutodiff (x, control_dual, time);
7461 return dynamics (i);
7562 };
7663
77- // Calculate gradient of the i-th output with respect to state
7864 J.row (i) = autodiff::gradient (dynamics_i, autodiff::wrt (state_dual), at (state_dual));
7965 }
8066
81- // Convert discrete Jacobian to continuous time Jacobian
8267 J.diagonal ().array () -= 1.0 ;
8368 J /= timestep_;
8469
@@ -87,54 +72,37 @@ Eigen::MatrixXd Car::getStateJacobian(
8772
8873Eigen::MatrixXd Car::getControlJacobian (
8974 const Eigen::VectorXd& state, const Eigen::VectorXd& control, double time) const {
90-
91- // Convert inputs to autodiff types
9275 VectorXdual2nd state_dual = state.cast <autodiff::dual2nd>();
9376 VectorXdual2nd control_dual = control.cast <autodiff::dual2nd>();
94-
95- // Initialize Jacobian
9677 Eigen::MatrixXd J = Eigen::MatrixXd::Zero (STATE_DIM, CONTROL_DIM);
9778
98- // Calculate Jacobian using autodiff
9979 for (int i = 0 ; i < STATE_DIM; ++i) {
100- // Create a lambda that returns the i-th component of the dynamics
10180 auto dynamics_i = [this , i, &state_dual, time](const VectorXdual2nd& u) -> autodiff::dual2nd {
10281 VectorXdual2nd dynamics = this ->getDiscreteDynamicsAutodiff (state_dual, u, time);
10382 return dynamics (i);
10483 };
10584
106- // Calculate gradient of the i-th output with respect to control
10785 J.row (i) = autodiff::gradient (dynamics_i, autodiff::wrt (control_dual), at (control_dual));
10886 }
10987
110- // Convert discrete Jacobian to continuous time Jacobian
11188 J /= timestep_;
11289
11390 return J;
11491}
11592
11693std::vector<Eigen::MatrixXd> Car::getStateHessian (
11794 const Eigen::VectorXd& state, const Eigen::VectorXd& control, double time) const {
118-
119- // Convert inputs to autodiff types
12095 VectorXdual2nd state_dual = state.cast <autodiff::dual2nd>();
12196 VectorXdual2nd control_dual = control.cast <autodiff::dual2nd>();
122-
123- // Initialize Hessians
12497 auto hessians = makeZeroTensor (STATE_DIM, STATE_DIM, STATE_DIM);
12598
126- // Calculate Hessians using autodiff
12799 for (int i = 0 ; i < STATE_DIM; ++i) {
128- // Create a lambda that returns the i-th component of the dynamics
129100 auto dynamics_i = [this , i, &control_dual, time](const VectorXdual2nd& x) -> autodiff::dual2nd {
130101 VectorXdual2nd dynamics = this ->getDiscreteDynamicsAutodiff (x, control_dual, time);
131102 return dynamics (i);
132103 };
133104
134- // Calculate Hessian of the i-th output with respect to state
135105 hessians[i] = autodiff::hessian (dynamics_i, autodiff::wrt (state_dual), at (state_dual));
136-
137- // Convert discrete Hessian to continuous time Hessian
138106 hessians[i] /= timestep_;
139107 }
140108
@@ -143,50 +111,36 @@ std::vector<Eigen::MatrixXd> Car::getStateHessian(
143111
144112std::vector<Eigen::MatrixXd> Car::getControlHessian (
145113 const Eigen::VectorXd& state, const Eigen::VectorXd& control, double time) const {
146-
147- // Convert inputs to autodiff types
148114 VectorXdual2nd state_dual = state.cast <autodiff::dual2nd>();
149115 VectorXdual2nd control_dual = control.cast <autodiff::dual2nd>();
150-
151- // Initialize Hessians
152116 auto hessians = makeZeroTensor (STATE_DIM, CONTROL_DIM, CONTROL_DIM);
153117
154- // Calculate Hessians using autodiff
155118 for (int i = 0 ; i < STATE_DIM; ++i) {
156- // Create a lambda that returns the i-th component of the dynamics
157119 auto dynamics_i = [this , i, &state_dual, time](const VectorXdual2nd& u) -> autodiff::dual2nd {
158120 VectorXdual2nd dynamics = this ->getDiscreteDynamicsAutodiff (state_dual, u, time);
159121 return dynamics (i);
160122 };
161123
162- // Calculate Hessian of the i-th output with respect to control
163124 hessians[i] = autodiff::hessian (dynamics_i, autodiff::wrt (control_dual), at (control_dual));
164-
165- // Convert discrete Hessian to continuous time Hessian
166125 hessians[i] /= timestep_;
167126 }
168127
169128 return hessians;
170129}
171130
172- // Helper: Autodiff version of discrete dynamics
173131cddp::VectorXdual2nd Car::getDiscreteDynamicsAutodiff (
174132 const VectorXdual2nd& state, const VectorXdual2nd& control, double time) const {
175133
176- // Extract states (dual2nd)
177134 const autodiff::dual2nd theta = state (STATE_THETA);
178135 const autodiff::dual2nd v = state (STATE_V);
179136
180- // Extract controls (dual2nd)
181137 const autodiff::dual2nd delta = control (CONTROL_DELTA);
182138 const autodiff::dual2nd a = control (CONTROL_A);
183139
184- // Constants
185140 const double d_double = wheelbase_;
186141 const double h = timestep_;
187142 const autodiff::dual2nd d = wheelbase_;
188143
189- // Use ADL for math functions
190144 const autodiff::dual2nd cos_theta = cos (theta);
191145 const autodiff::dual2nd sin_theta = sin (theta);
192146
@@ -228,4 +182,4 @@ cddp::VectorXdual2nd Car::getContinuousDynamicsAutodiff(
228182 return (next_state - state) / timestep_;
229183}
230184
231- } // namespace cddp
185+ } // namespace cddp
0 commit comments