52 #include <ilqgames/dynamics/single_player_flat_car_6d.h> 53 #include <ilqgames/dynamics/single_player_flat_system.h> 54 #include <ilqgames/utils/types.h> 56 #include <glog/logging.h> 61 const Dimension SinglePlayerFlatCar6D::kNumXDims = 6;
62 const Dimension SinglePlayerFlatCar6D::kPxIdx = 0;
63 const Dimension SinglePlayerFlatCar6D::kPyIdx = 1;
64 const Dimension SinglePlayerFlatCar6D::kThetaIdx = 2;
65 const Dimension SinglePlayerFlatCar6D::kPhiIdx = 3;
66 const Dimension SinglePlayerFlatCar6D::kVIdx = 4;
67 const Dimension SinglePlayerFlatCar6D::kAIdx = 5;
68 const Dimension SinglePlayerFlatCar6D::kVxIdx = 2;
69 const Dimension SinglePlayerFlatCar6D::kVyIdx = 3;
70 const Dimension SinglePlayerFlatCar6D::kAxIdx = 4;
71 const Dimension SinglePlayerFlatCar6D::kAyIdx = 5;
74 const Dimension SinglePlayerFlatCar6D::kNumUDims = 2;
75 const Dimension SinglePlayerFlatCar6D::kOmegaIdx = 0;
76 const Dimension SinglePlayerFlatCar6D::kJerkIdx = 1;
78 void SinglePlayerFlatCar6D::Partial(
const VectorXf& xi,
79 std::vector<VectorXf>* grads,
80 std::vector<MatrixXf>* hesses)
const {
82 CHECK_NOTNULL(hesses);
90 if (grads->size() != xi.size())
91 grads->resize(xi.size(), VectorXf::Zero(kNumXDims));
93 for (
auto& grad : *grads) {
94 DCHECK_EQ(grad.size(), xi.size());
99 if (hesses->size() != xi.size())
100 hesses->resize(xi.size(), MatrixXf::Zero(kNumXDims, kNumXDims));
102 for (
auto& hess : *hesses) {
103 DCHECK_EQ(hess.rows(), xi.size());
104 DCHECK_EQ(hess.cols(), xi.size());
109 const float vx = xi(kVxIdx);
110 const float vy = xi(kVyIdx);
111 const float ax = xi(kAxIdx);
112 const float ay = xi(kAyIdx);
113 const float L = inter_axle_distance_;
115 CHECK_GT(std::hypot(vx, vy), 1e-2);
117 const float vx2 = vx * vx;
118 const float vx3 = vx2 * vx;
119 const float vx4 = vx3 * vx;
120 const float vx5 = vx4 * vx;
121 const float vx6 = vx5 * vx;
122 const float vx7 = vx6 * vx;
123 const float vx8 = vx7 * vx;
124 const float vx9 = vx8 * vx;
126 const float vy2 = vy * vy;
127 const float vy3 = vy2 * vy;
128 const float vy4 = vy3 * vy;
129 const float vy5 = vy4 * vy;
130 const float vy6 = vy5 * vy;
131 const float vy7 = vy6 * vy;
132 const float vy8 = vy7 * vy;
133 const float vy9 = vy8 * vy;
135 const float ax2 = ax * ax;
136 const float ax3 = ax2 * ax;
137 const float ay2 = ay * ay;
138 const float ay3 = ay2 * ay;
140 const float L2 = L * L;
142 const float norm_squared = vx2 + vy2;
143 const float norm = std::sqrt(norm_squared);
144 const float norm_ss = norm_squared * norm_squared;
145 const float norm_sss = norm_ss * norm_squared;
146 const float sqrt_norm_sss = std::sqrt(norm_sss);
148 (*grads)[kPxIdx](kPxIdx) = 1.0;
149 (*grads)[kPyIdx](kPyIdx) = 1.0;
150 (*grads)[kThetaIdx](kVxIdx) = -vy / norm_squared;
151 (*grads)[kThetaIdx](kVyIdx) = vx / norm_squared;
152 (*grads)[kVIdx](kVxIdx) = vx / norm;
153 (*grads)[kVIdx](kVyIdx) = vy / norm;
155 (*grads)[kAIdx](kVxIdx) = vy * (ax * vy - ay * vx) / sqrt_norm_sss;
156 (*grads)[kAIdx](kVyIdx) = vx * (ay * vx - ax * vy) / sqrt_norm_sss;
157 (*grads)[kAIdx](kAxIdx) = (*grads)[kVIdx](kVxIdx);
158 (*grads)[kAIdx](kAyIdx) = (*grads)[kVIdx](kVyIdx);
159 (*grads)[kPhiIdx](kVxIdx) =
160 (L * norm * (-2.0 * ay * vx2 + 3.0 * ax * vx * vy + ay * vy2)) /
161 (L * L * ax2 * vy2 - 2.0 * L2 * ax * ay * vx * vy + L2 * ay2 * vx2 + vx6 +
162 3.0 * vx4 * vy2 + 3.0 * vx2 * vy4 + vy4);
163 (*grads)[kPhiIdx](kVyIdx) =
164 -(L * norm * (ax * vx2 + 3.0 * ay * vx * vy - 2.0 * ax * vy2)) /
165 (L2 * ax * ax * vy2 - 2.0 * L2 * ax * ay * vx * vy + L2 * ay2 * vx2 +
166 vx6 + 3.0 * vx4 * vy2 + 3.0 * vx2 * vy4 + vy6);
167 (*grads)[kPhiIdx](kAxIdx) = -(L * vy * sqrt_norm_sss) /
168 (norm_ss * norm_squared + L2 * ax2 * vy2 +
169 L2 * ay2 * vx2 - 2.0 * L2 * ax * ay * vx * vy);
170 (*grads)[kPhiIdx](kAyIdx) = (L * vx * sqrt_norm_sss) /
171 (norm_ss * norm_squared + L2 * ax2 * vy2 +
172 L2 * ay2 * vx2 - 2.0 * L2 * ax * ay * vx * vy);
174 (*hesses)[kThetaIdx](kVxIdx, kVxIdx) = 2.0 * vx * vy / norm_ss;
175 (*hesses)[kThetaIdx](kVxIdx, kVyIdx) = (vy * vy - vx * vx) / norm_ss;
176 (*hesses)[kThetaIdx](kVyIdx, kVxIdx) = (*hesses)[kThetaIdx](kVxIdx, kVyIdx);
177 (*hesses)[kThetaIdx](kVyIdx, kVyIdx) = -(*hesses)[kThetaIdx](kVxIdx, kVxIdx);
178 (*hesses)[kVIdx](kVxIdx, kVxIdx) = (vy * vy) / sqrt_norm_sss;
179 (*hesses)[kVIdx](kVxIdx, kVyIdx) = (-vx * vy) / sqrt_norm_sss;
180 (*hesses)[kVIdx](kVyIdx, kVxIdx) = (*hesses)[kVIdx](kVxIdx, kVyIdx);
181 (*hesses)[kVIdx](kVyIdx, kVyIdx) = (vx * vx) / sqrt_norm_sss;
183 (*hesses)[kAIdx](kVxIdx, kVxIdx) =
184 -(vy * (-2.0 * ay * vx2 + 3.0 * ax * vx * vy + ay * vy2)) /
185 (sqrt_norm_sss * norm);
186 (*hesses)[kAIdx](kVxIdx, kVyIdx) =
187 -(ay * vx3 - 2.0 * ax * vx2 * vy - 2.0 * ay * vx * vy2 + ax * vy3) /
188 (sqrt_norm_sss * norm);
189 (*hesses)[kAIdx](kVxIdx, kAxIdx) = vy2 / sqrt_norm_sss;
190 (*hesses)[kAIdx](kVxIdx, kAyIdx) = -(vx * vy) / sqrt_norm_sss;
191 (*hesses)[kAIdx](kVyIdx, kVxIdx) = (*hesses)[kAIdx](kVxIdx, kVyIdx);
192 (*hesses)[kAIdx](kVyIdx, kVyIdx) =
193 -(vx * (ax * vx2 + 3.0 * ay * vx * vy - 2.0 * ax * vy2)) /
194 (sqrt_norm_sss * norm);
195 (*hesses)[kAIdx](kVyIdx, kAxIdx) = -(vx * vy) / sqrt_norm_sss;
196 (*hesses)[kAIdx](kVyIdx, kAyIdx) = vx2 / sqrt_norm_sss;
197 (*hesses)[kAIdx](kAxIdx, kVxIdx) = (*hesses)[kAIdx](kVxIdx, kAxIdx);
198 (*hesses)[kAIdx](kAxIdx, kVyIdx) = (*hesses)[kAIdx](kVyIdx, kAxIdx);
199 (*hesses)[kAIdx](kAyIdx, kVxIdx) = (*hesses)[kAIdx](kVxIdx, kAyIdx);
200 (*hesses)[kAIdx](kAyIdx, kVyIdx) = (*hesses)[kAIdx](kVyIdx, kAyIdx);
203 (L2 * ax2 * vy2 - 2 * L2 * ax * ay * vx * vy + L2 * ay2 * vx2 + vx6 +
204 3 * vx4 * vy2 + 3 * vx2 * vy4 + vy6);
206 (norm_sss + L2 * ax2 * vy2 + L2 * ay2 * vx2 - 2 * L2 * ax * ay * vx * vy);
207 (*hesses)[kPhiIdx](kVxIdx, kVxIdx) =
209 (-6 * L2 * ax3 * vx2 * vy3 - 3 * L2 * ax3 * vy5 +
210 12 * L2 * ax2 * ay * vx3 * vy2 + 3 * L2 * ax2 * ay * vx * vy4 -
211 8 * L2 * ax * ay2 * vx4 * vy - L2 * ax * ay2 * vx2 * vy3 -
212 2 * L2 * ax * ay2 * vy5 + 2 * L2 * ay3 * vx5 + L2 * ay3 * vx3 * vy2 +
213 2 * L2 * ay3 * vx * vy4 + 12 * ax * vx8 * vy + 33 * ax * vx6 * vy3 +
214 27 * ax * vx4 * vy5 + 3 * ax * vx2 * vy7 - 3 * ax * vy9 -
215 6 * ay * vx9 - 9 * ay * vx7 * vy2 + 9 * ay * vx5 * vy4 +
216 21 * ay * vx3 * vy6 + 9 * ay * vx * vy8)) /
217 (norm * denom * denom);
218 (*hesses)[kPhiIdx](kVxIdx, kVyIdx) =
220 (-3 * L2 * ax3 * vx3 * vy2 + 4 * L2 * ax2 * ay * vx4 * vy -
221 4 * L2 * ax2 * ay * vx2 * vy3 + L2 * ax2 * ay * vy5 -
222 L2 * ax * ay2 * vx5 + 4 * L2 * ax * ay2 * vx3 * vy2 -
223 4 * L2 * ax * ay2 * vx * vy4 + 3 * L2 * ay3 * vx2 * vy3 + 3 * ax * vx9 -
224 3 * ax * vx7 * vy2 - 27 * ax * vx5 * vy4 - 33 * ax * vx3 * vy6 -
225 12 * ax * vx * vy8 + 12 * ay * vx8 * vy + 33 * ay * vx6 * vy3 +
226 27 * ay * vx4 * vy5 + 3 * ay * vx2 * vy7 - 3 * ay * vy9)) /
227 (norm * denom * denom);
228 (*hesses)[kPhiIdx](kVxIdx, kAxIdx) =
230 (-3 * L2 * ax2 * vx * vy2 + 4 * L2 * ax * ay * vx2 * vy -
231 2 * L2 * ax * ay * vy3 - L2 * ay2 * vx3 + 2 * L2 * ay2 * vx * vy2 +
232 3 * vx7 + 9 * vx5 * vy2 + 9 * vx3 * vy4 + 3 * vx * vy6)) /
234 (*hesses)[kPhiIdx](kVxIdx, kAyIdx) =
236 (4 * L2 * ax2 * vx2 * vy2 + L2 * ax2 * vy4 -
237 6 * L2 * ax * ay * vx3 * vy + 2 * L2 * ay2 * vx4 -
238 L2 * ay2 * vx2 * vy2 - 2 * vx8 - 5 * vx6 * vy2 - 3 * vx4 * vy4 +
241 (*hesses)[kPhiIdx](kVyIdx, kVxIdx) = (*hesses)[kAIdx](kVxIdx, kVyIdx);
242 (*hesses)[kPhiIdx](kVyIdx, kVyIdx) =
243 (L * (2 * L2 * ax3 * vx4 * vy + L2 * ax3 * vx2 * vy3 +
244 2 * L2 * ax3 * vy5 - 2 * L2 * ax2 * ay * vx5 -
245 L2 * ax2 * ay * vx3 * vy2 - 8 * L2 * ax2 * ay * vx * vy4 +
246 3 * L2 * ax * ay2 * vx4 * vy + 12 * L2 * ax * ay2 * vx2 * vy3 -
247 3 * L2 * ay3 * vx5 - 6 * L2 * ay3 * vx3 * vy2 + 9 * ax * vx8 * vy +
248 21 * ax * vx6 * vy3 + 9 * ax * vx4 * vy5 - 9 * ax * vx2 * vy7 -
249 6 * ax * vy9 - 3 * ay * vx9 + 3 * ay * vx7 * vy2 +
250 27 * ay * vx5 * vy4 + 33 * ay * vx3 * vy6 + 12 * ay * vx * vy8)) /
251 (norm * denom * denom);
252 (*hesses)[kPhiIdx](kVyIdx, kAxIdx) =
254 (L2 * ax2 * vx2 * vy2 - 2 * L2 * ax2 * vy4 +
255 6 * L2 * ax * ay * vx * vy3 - L2 * ay2 * vx4 -
256 4 * L2 * ay2 * vx2 * vy2 - vx8 - vx6 * vy2 + 3 * vx4 * vy4 +
257 5 * vx2 * vy6 + 2 * vy8)) /
259 (*hesses)[kPhiIdx](kVyIdx, kAyIdx) =
261 (2 * L2 * ax2 * vx2 * vy - L2 * ax2 * vy3 - 2 * L2 * ax * ay * vx3 +
262 4 * L2 * ax * ay * vx * vy2 - 3 * L2 * ay2 * vx2 * vy + 3 * vx6 * vy +
263 9 * vx4 * vy3 + 9 * vx2 * vy5 + 3 * vy7)) /
265 (*hesses)[kPhiIdx](kAxIdx, kVxIdx) = (*hesses)[kPhiIdx](kVxIdx, kAxIdx);
266 (*hesses)[kPhiIdx](kAxIdx, kVyIdx) = (*hesses)[kPhiIdx](kVyIdx, kAxIdx);
267 (*hesses)[kPhiIdx](kAxIdx, kAxIdx) =
268 (L * vy * sqrt_norm_sss * (2 * ax * L2 * vy2 - 2 * ay * vx * L2 * vy)) /
270 (*hesses)[kPhiIdx](kAxIdx, kAyIdx) =
271 (L * vy * sqrt_norm_sss * (2 * ay * L2 * vx2 - 2 * ax * vy * L2 * vx)) /
273 (*hesses)[kPhiIdx](kAyIdx, kVxIdx) = (*hesses)[kPhiIdx](kVxIdx, kAyIdx);
274 (*hesses)[kPhiIdx](kAyIdx, kVyIdx) = (*hesses)[kPhiIdx](kVyIdx, kAyIdx);
275 (*hesses)[kPhiIdx](kAyIdx, kAxIdx) = (*hesses)[kPhiIdx](kAxIdx, kAyIdx);
276 (*hesses)[kPhiIdx](kAyIdx, kAyIdx) =
277 -(L * vx * sqrt_norm_sss * (2 * ay * L2 * vx2 - 2 * ax * vy * L2 * vx)) /