30 for (
size_t i = 0; i < traj_points.size() - 1; i++) {
31 sumdt += traj_points.at(i + 1)(0) - traj_points.at(i)(0);
33 dt = sumdt / (traj_points.size() - 1);
34 dt = (
dt < 0.05) ? 0.05 :
dt;
35 PRINT_DEBUG(
"[B-SPLINE]: control point dt = %.3f (original dt of %.3f)\n",
dt, sumdt / (traj_points.size() - 1));
40 for (
size_t i = 0; i < traj_points.size() - 1; i++) {
41 Eigen::Matrix4d T_IinG = Eigen::Matrix4d::Identity();
42 T_IinG.block(0, 0, 3, 3) =
quat_2_Rot(traj_points.at(i).block(4, 0, 4, 1)).transpose();
43 T_IinG.block(0, 3, 3, 1) = traj_points.at(i).block(1, 0, 3, 1);
44 trajectory_points.insert({traj_points.at(i)(0), T_IinG});
48 double timestamp_min = INFINITY;
49 double timestamp_max = -INFINITY;
50 for (
const auto &pose : trajectory_points) {
51 if (pose.first <= timestamp_min) {
52 timestamp_min = pose.first;
54 if (pose.first >= timestamp_max) {
55 timestamp_max = pose.first;
58 PRINT_DEBUG(
"[B-SPLINE]: trajectory start time = %.6f\n", timestamp_min);
59 PRINT_DEBUG(
"[B-SPLINE]: trajectory end time = %.6f\n", timestamp_max);
62 double timestamp_curr = timestamp_min;
67 Eigen::Matrix4d pose0, pose1;
68 bool success =
find_bounding_poses(timestamp_curr, trajectory_points, t0, pose0, t1, pose1);
78 double lambda = (timestamp_curr - t0) / (t1 - t0);
95 double t0, t1, t2, t3;
96 Eigen::Matrix4d pose0, pose1, pose2, pose3;
103 R_GtoI.setIdentity();
109 double DT = (t2 - t1);
110 double u = (timestamp - t1) / DT;
111 double b0 = 1.0 / 6.0 * (5 + 3 * u - 3 * u * u + u * u * u);
112 double b1 = 1.0 / 6.0 * (1 + 3 * u + 3 * u * u - 2 * u * u * u);
113 double b2 = 1.0 / 6.0 * (u * u * u);
121 Eigen::Matrix4d pose_interp = pose0 * A0 * A1 * A2;
122 R_GtoI = pose_interp.block(0, 0, 3, 3).transpose();
123 p_IinG = pose_interp.block(0, 3, 3, 1);
128 Eigen::Vector3d &v_IinG) {
131 double t0, t1, t2, t3;
132 Eigen::Matrix4d pose0, pose1, pose2, pose3;
145 double DT = (t2 - t1);
146 double u = (timestamp - t1) / DT;
147 double b0 = 1.0 / 6.0 * (5 + 3 * u - 3 * u * u + u * u * u);
148 double b1 = 1.0 / 6.0 * (1 + 3 * u + 3 * u * u - 2 * u * u * u);
149 double b2 = 1.0 / 6.0 * (u * u * u);
150 double b0dot = 1.0 / (6.0 * DT) * (3 - 6 * u + 3 * u * u);
151 double b1dot = 1.0 / (6.0 * DT) * (3 + 6 * u - 6 * u * u);
152 double b2dot = 1.0 / (6.0 * DT) * (3 * u * u);
155 Eigen::Matrix<double, 6, 1> omega_10 =
log_se3(
Inv_se3(pose0) * pose1);
156 Eigen::Matrix<double, 6, 1> omega_21 =
log_se3(
Inv_se3(pose1) * pose2);
157 Eigen::Matrix<double, 6, 1> omega_32 =
log_se3(
Inv_se3(pose2) * pose3);
160 Eigen::Matrix4d A0 =
exp_se3(b0 * omega_10);
161 Eigen::Matrix4d A1 =
exp_se3(b1 * omega_21);
162 Eigen::Matrix4d A2 =
exp_se3(b2 * omega_32);
163 Eigen::Matrix4d A0dot = b0dot *
hat_se3(omega_10) * A0;
164 Eigen::Matrix4d A1dot = b1dot *
hat_se3(omega_21) * A1;
165 Eigen::Matrix4d A2dot = b2dot *
hat_se3(omega_32) * A2;
168 Eigen::Matrix4d pose_interp = pose0 * A0 * A1 * A2;
169 R_GtoI = pose_interp.block(0, 0, 3, 3).transpose();
170 p_IinG = pose_interp.block(0, 3, 3, 1);
174 Eigen::Matrix4d vel_interp = pose0 * (A0dot * A1 * A2 + A0 * A1dot * A2 + A0 * A1 * A2dot);
175 w_IinI =
vee(pose_interp.block(0, 0, 3, 3).transpose() * vel_interp.block(0, 0, 3, 3));
176 v_IinG = vel_interp.block(0, 3, 3, 1);
181 Eigen::Vector3d &v_IinG, Eigen::Vector3d &alpha_IinI, Eigen::Vector3d &a_IinG) {
184 double t0, t1, t2, t3;
185 Eigen::Matrix4d pose0, pose1, pose2, pose3;
190 alpha_IinI.setZero();
196 double DT = (t2 - t1);
197 double u = (timestamp - t1) / DT;
198 double b0 = 1.0 / 6.0 * (5 + 3 * u - 3 * u * u + u * u * u);
199 double b1 = 1.0 / 6.0 * (1 + 3 * u + 3 * u * u - 2 * u * u * u);
200 double b2 = 1.0 / 6.0 * (u * u * u);
201 double b0dot = 1.0 / (6.0 * DT) * (3 - 6 * u + 3 * u * u);
202 double b1dot = 1.0 / (6.0 * DT) * (3 + 6 * u - 6 * u * u);
203 double b2dot = 1.0 / (6.0 * DT) * (3 * u * u);
204 double b0dotdot = 1.0 / (6.0 * DT * DT) * (-6 + 6 * u);
205 double b1dotdot = 1.0 / (6.0 * DT * DT) * (6 - 12 * u);
206 double b2dotdot = 1.0 / (6.0 * DT * DT) * (6 * u);
209 Eigen::Matrix<double, 6, 1> omega_10 =
log_se3(
Inv_se3(pose0) * pose1);
210 Eigen::Matrix<double, 6, 1> omega_21 =
log_se3(
Inv_se3(pose1) * pose2);
211 Eigen::Matrix<double, 6, 1> omega_32 =
log_se3(
Inv_se3(pose2) * pose3);
212 Eigen::Matrix4d omega_10_hat =
hat_se3(omega_10);
213 Eigen::Matrix4d omega_21_hat =
hat_se3(omega_21);
214 Eigen::Matrix4d omega_32_hat =
hat_se3(omega_32);
217 Eigen::Matrix4d A0 =
exp_se3(b0 * omega_10);
218 Eigen::Matrix4d A1 =
exp_se3(b1 * omega_21);
219 Eigen::Matrix4d A2 =
exp_se3(b2 * omega_32);
220 Eigen::Matrix4d A0dot = b0dot * omega_10_hat * A0;
221 Eigen::Matrix4d A1dot = b1dot * omega_21_hat * A1;
222 Eigen::Matrix4d A2dot = b2dot * omega_32_hat * A2;
223 Eigen::Matrix4d A0dotdot = b0dot * omega_10_hat * A0dot + b0dotdot * omega_10_hat * A0;
224 Eigen::Matrix4d A1dotdot = b1dot * omega_21_hat * A1dot + b1dotdot * omega_21_hat * A1;
225 Eigen::Matrix4d A2dotdot = b2dot * omega_32_hat * A2dot + b2dotdot * omega_32_hat * A2;
228 Eigen::Matrix4d pose_interp = pose0 * A0 * A1 * A2;
229 R_GtoI = pose_interp.block(0, 0, 3, 3).transpose();
230 p_IinG = pose_interp.block(0, 3, 3, 1);
234 Eigen::Matrix4d vel_interp = pose0 * (A0dot * A1 * A2 + A0 * A1dot * A2 + A0 * A1 * A2dot);
235 w_IinI =
vee(pose_interp.block(0, 0, 3, 3).transpose() * vel_interp.block(0, 0, 3, 3));
236 v_IinG = vel_interp.block(0, 3, 3, 1);
241 Eigen::Matrix4d acc_interp = pose0 * (A0dotdot * A1 * A2 + A0 * A1dotdot * A2 + A0 * A1 * A2dotdot + 2 * A0dot * A1dot * A2 +
242 2 * A0 * A1dot * A2dot + 2 * A0dot * A1 * A2dot);
243 Eigen::Matrix3d omegaskew = pose_interp.block(0, 0, 3, 3).transpose() * vel_interp.block(0, 0, 3, 3);
244 alpha_IinI =
vee(pose_interp.block(0, 0, 3, 3).transpose() * (acc_interp.block(0, 0, 3, 3) - vel_interp.block(0, 0, 3, 3) * omegaskew));
245 a_IinG = acc_interp.block(0, 3, 3, 1);
250 Eigen::Matrix4d &pose1) {
255 pose0 = Eigen::Matrix4d::Identity();
256 pose1 = Eigen::Matrix4d::Identity();
259 bool found_older =
false;
260 bool found_newer =
false;
263 auto lower_bound = poses.lower_bound(timestamp);
264 auto upper_bound = poses.upper_bound(timestamp);
266 if (lower_bound != poses.end()) {
269 if (lower_bound->first == timestamp) {
271 }
else if (lower_bound != poses.begin()) {
277 if (upper_bound != poses.end()) {
283 t0 = lower_bound->first;
284 pose0 = lower_bound->second;
289 t1 = upper_bound->first;
290 pose1 = upper_bound->second;
294 if (found_older && found_newer)
298 return (found_older && found_newer);
302 double &t1, Eigen::Matrix4d &pose1,
double &t2, Eigen::Matrix4d &pose2,
double &t3,
303 Eigen::Matrix4d &pose3) {
310 pose0 = Eigen::Matrix4d::Identity();
311 pose1 = Eigen::Matrix4d::Identity();
312 pose2 = Eigen::Matrix4d::Identity();
313 pose3 = Eigen::Matrix4d::Identity();
323 auto iter_t1 = poses.find(t1);
324 auto iter_t2 = poses.find(t2);
327 if (iter_t1 == poses.begin()) {
333 auto iter_t0 = --iter_t1;
334 auto iter_t3 = ++iter_t2;
337 if (iter_t3 == poses.end()) {
343 pose0 = iter_t0->second;
347 pose3 = iter_t3->second;