1
+ #ifndef CDDP_BICYCLE_HPP
2
+ #define CDDP_BICYCLE_HPP
3
+
4
+ #include " Eigen/Dense"
5
+ #include < vector>
6
+ #include " cddp_core/DynamicalSystem.hpp"
7
+
8
+ namespace cddp {
9
+
10
+ class Bicycle : public cddp ::DynamicalSystem {
11
+ public:
12
+ int state_size_; // State dimension (x, y, theta, v)
13
+ int control_size_; // Control dimension (a, delta)
14
+ double timestep_; // Time step
15
+ double wheelbase_; // Distance between front and rear axles
16
+ int integration_type_;
17
+
18
+ Bicycle (int state_dim, int control_dim, double timestep, double wheelbase, int integration_type) :
19
+ DynamicalSystem (state_dim, control_dim, timestep, integration_type) {
20
+ state_size_ = state_dim; // Should be 4: [x, y, theta, v]
21
+ control_size_ = control_dim; // Should be 2: [acceleration, steering_angle]
22
+ timestep_ = timestep;
23
+ wheelbase_ = wheelbase;
24
+ integration_type_ = integration_type;
25
+ }
26
+
27
+ Eigen::VectorXd dynamics (const Eigen::VectorXd &state, const Eigen::VectorXd &control) override {
28
+ // State: [x, y, theta, v]
29
+ // Control: [acceleration, steering_angle]
30
+ Eigen::VectorXd state_dot = Eigen::VectorXd::Zero (state_size_);
31
+
32
+ double v = state (3 ); // velocity
33
+ double theta = state (2 ); // heading angle
34
+ double delta = control (1 ); // steering angle
35
+ double a = control (0 ); // acceleration
36
+
37
+ // Kinematic bicycle model equations
38
+ state_dot (0 ) = v * cos (theta); // dx/dt
39
+ state_dot (1 ) = v * sin (theta); // dy/dt
40
+ state_dot (2 ) = (v / wheelbase_) * tan (delta); // dtheta/dt
41
+ state_dot (3 ) = a; // dv/dt
42
+
43
+ return state_dot;
44
+ }
45
+
46
+ std::tuple<Eigen::MatrixXd, Eigen::MatrixXd> getDynamicsJacobian (
47
+ const Eigen::VectorXd &state, const Eigen::VectorXd &control) override {
48
+ // Initialize Jacobian matrices
49
+ Eigen::MatrixXd A = Eigen::MatrixXd::Zero (state_size_, state_size_); // df/dx
50
+ Eigen::MatrixXd B = Eigen::MatrixXd::Zero (state_size_, control_size_); // df/du
51
+
52
+ double v = state (3 ); // velocity
53
+ double theta = state (2 ); // heading angle
54
+ double delta = control (1 ); // steering angle
55
+
56
+ // State Jacobian (A matrix)
57
+ // df1/dx = d(dx/dt)/dx
58
+ A (0 , 2 ) = -v * sin (theta); // df1/dtheta
59
+ A (0 , 3 ) = cos (theta); // df1/dv
60
+
61
+ // df2/dx = d(dy/dt)/dx
62
+ A (1 , 2 ) = v * cos (theta); // df2/dtheta
63
+ A (1 , 3 ) = sin (theta); // df2/dv
64
+
65
+ // df3/dx = d(dtheta/dt)/dx
66
+ A (2 , 3 ) = tan (delta) / wheelbase_; // df3/dv
67
+
68
+ // Control Jacobian (B matrix)
69
+ // df/du
70
+ B (3 , 0 ) = 1.0 ; // df4/da (acceleration effect on velocity)
71
+ B (2 , 1 ) = v / (wheelbase_ * pow (cos (delta), 2 )); // df3/ddelta
72
+
73
+ return std::make_tuple (A, B);
74
+ }
75
+
76
+ std::tuple<Eigen::MatrixXd, Eigen::MatrixXd, Eigen::MatrixXd> getDynamicsHessian (
77
+ const Eigen::VectorXd &state, const Eigen::VectorXd &control) override {
78
+ // Initialize Hessian matrices
79
+ Eigen::MatrixXd hxx = Eigen::MatrixXd::Zero (state_size_ * state_size_, state_size_);
80
+ Eigen::MatrixXd hxu = Eigen::MatrixXd::Zero (state_size_ * control_size_, state_size_);
81
+ Eigen::MatrixXd huu = Eigen::MatrixXd::Zero (state_size_ * control_size_, control_size_);
82
+
83
+ double v = state (3 ); // velocity
84
+ double theta = state (2 ); // heading angle
85
+ double delta = control (1 ); // steering angle
86
+
87
+ // Fill in non-zero Hessian terms
88
+ // Second derivatives with respect to states
89
+ int idx;
90
+
91
+ // d²(dx/dt)/dtheta²
92
+ idx = 2 * state_size_ + 0 ; // (theta, x) component
93
+ hxx (idx, 2 ) = -v * cos (theta);
94
+
95
+ // d²(dy/dt)/dtheta²
96
+ idx = 2 * state_size_ + 1 ; // (theta, y) component
97
+ hxx (idx, 2 ) = -v * sin (theta);
98
+
99
+ // Mixed derivatives (state-control)
100
+ // d²(dtheta/dt)/dv/ddelta
101
+ idx = 3 * control_size_ + 1 ; // (v, delta) component
102
+ hxu (idx, 2 ) = 1.0 / (wheelbase_ * pow (cos (delta), 2 ));
103
+
104
+ // Second derivatives with respect to controls
105
+ // d²(dtheta/dt)/ddelta²
106
+ idx = 1 * control_size_ + 2 ; // (delta, theta) component
107
+ huu (idx, 1 ) = 2.0 * v * sin (delta) / (wheelbase_ * pow (cos (delta), 3 ));
108
+
109
+ return std::make_tuple (hxx, hxu, huu);
110
+ }
111
+ };
112
+
113
+ } // namespace cddp
114
+
115
+ #endif // CDDP_BICYCLE_HPP
0 commit comments