55 #ifndef ILQGAMES_DYNAMICS_SINGLE_PLAYER_CAR_7D_H 56 #define ILQGAMES_DYNAMICS_SINGLE_PLAYER_CAR_7D_H 58 #include <ilqgames/dynamics/single_player_dynamical_system.h> 59 #include <ilqgames/utils/types.h> 68 inter_axle_distance_(inter_axle_distance) {}
71 VectorXf Evaluate(Time t,
const VectorXf& x,
const VectorXf& u)
const;
74 void Linearize(Time t,
const VectorXf& x,
const VectorXf& u,
75 Eigen::Ref<MatrixXf> A, Eigen::Ref<MatrixXf> B)
const;
78 float DistanceBetween(
const VectorXf& x0,
const VectorXf& x1)
const;
81 std::vector<Dimension> PositionDimensions()
const {
return {kPxIdx, kPyIdx}; }
84 static const Dimension kNumXDims;
85 static const Dimension kPxIdx;
86 static const Dimension kPyIdx;
87 static const Dimension kThetaIdx;
88 static const Dimension kPhiIdx;
89 static const Dimension kVIdx;
90 static const Dimension kKappaIdx;
91 static const Dimension kSIdx;
94 static const Dimension kNumUDims;
95 static const Dimension kOmegaIdx;
96 static const Dimension kAIdx;
100 const float inter_axle_distance_;
105 inline VectorXf SinglePlayerCar7D::Evaluate(Time t,
const VectorXf& x,
106 const VectorXf& u)
const {
107 VectorXf xdot(xdim_);
108 xdot(kPxIdx) = x(kVIdx) * std::cos(x(kThetaIdx));
109 xdot(kPyIdx) = x(kVIdx) * std::sin(x(kThetaIdx));
110 xdot(kThetaIdx) = (x(kVIdx) / inter_axle_distance_) * std::tan(x(kPhiIdx));
111 xdot(kPhiIdx) = u(kOmegaIdx);
112 xdot(kVIdx) = u(kAIdx);
114 const float sec_phi = 1.0 / std::cos(x(kPhiIdx));
115 xdot(kKappaIdx) = u(kOmegaIdx) * sec_phi * sec_phi / inter_axle_distance_;
116 xdot(kSIdx) = x(kVIdx);
121 inline void SinglePlayerCar7D::Linearize(Time t,
const VectorXf& x,
123 Eigen::Ref<MatrixXf> A,
124 Eigen::Ref<MatrixXf> B)
const {
125 const float ctheta = std::cos(x(kThetaIdx)) * time::kTimeStep;
126 const float stheta = std::sin(x(kThetaIdx)) * time::kTimeStep;
127 const float cphi = std::cos(x(kPhiIdx));
128 const float tphi = std::tan(x(kPhiIdx));
130 A(kPxIdx, kThetaIdx) += -x(kVIdx) * stheta;
131 A(kPxIdx, kVIdx) += ctheta;
133 A(kPyIdx, kThetaIdx) += x(kVIdx) * ctheta;
134 A(kPyIdx, kVIdx) += stheta;
136 A(kThetaIdx, kPhiIdx) +=
137 x(kVIdx) * time::kTimeStep / (inter_axle_distance_ * cphi * cphi);
138 A(kThetaIdx, kVIdx) += tphi * time::kTimeStep / inter_axle_distance_;
140 A(kKappaIdx, kPhiIdx) += 2.0 * time::kTimeStep * u(kOmegaIdx) * tphi /
141 (cphi * cphi * inter_axle_distance_);
143 A(kSIdx, kVIdx) += time::kTimeStep;
145 B(kPhiIdx, kOmegaIdx) = time::kTimeStep;
146 B(kVIdx, kAIdx) = time::kTimeStep;
147 B(kKappaIdx, kOmegaIdx) =
148 time::kTimeStep / (cphi * cphi * inter_axle_distance_);
151 inline float SinglePlayerCar7D::DistanceBetween(
const VectorXf& x0,
152 const VectorXf& x1)
const {
154 const float dx = x0(kPxIdx) - x1(kPxIdx);
155 const float dy = x0(kPyIdx) - x1(kPyIdx);
156 return dx * dx + dy * dy;