17 #define USE_INITIAL_GUESS 25 extern std::ofstream update_log;
28 int pSim::Update(
double timestep, std::vector<SDContactPair*>& sdContactPairs)
31 int n_pairs = sdContactPairs.size();
37 update_log <<
"Update(" << timestep <<
")" << endl;
39 int n_total_points = 0;
41 update_log <<
"num pairs = " << n_pairs << endl;
46 for(
int i=0;
i<n_pairs;
i++)
52 if(n_points == 0)
continue;
54 update_log <<
"== [" << pjoint->
name <<
", " << rjoint->
name <<
"]: contact points = " << n_points << endl;
57 static fVec3 rjoint_lin_vel, rjoint_ang_vel, rjoint_pos, temp;
58 static fMat33 t_p_att, rjoint_att, t_rjoint_att;
61 rjoint_pos.
mul(t_p_att, temp);
65 t_rjoint_att.
tran(rjoint_att);
67 update_log << rjoint->
name <<
": rel_lin_vel = " << rjoint->
rel_lin_vel << endl;
68 update_log << rjoint->
name <<
": rel_ang_vel = " << rjoint->
rel_ang_vel << endl;
71 std::vector<fVec3> pair_positions;
72 std::vector<fVec3> pair_normals;
73 std::vector<fVec3> pair_relvels;
74 std::vector<fVec3> pair_positions_real;
75 std::vector<fMat33> pair_orientations;
76 std::vector<fMat33> pair_orientations_real;
77 std::vector<fVec3> pair_jdot;
78 std::vector<fVec3> pair_jdot_real;
79 for(
int m=0; m<n_points; m++)
82 update_log <<
"- contact point " << m << endl;
89 static fVec3 relpos1, relpos2, relnorm;
91 relpos1(0) = sd_pair->
Coord(m)(0);
92 relpos1(1) = sd_pair->
Coord(m)(1);
93 relpos1(2) = sd_pair->
Coord(m)(2);
95 relnorm(0) = sd_pair->
Normal(m)(0);
96 relnorm(1) = sd_pair->
Normal(m)(1);
97 relnorm(2) = sd_pair->
Normal(m)(2);
99 depth = sd_pair->
Depth(m);
101 update_log <<
"p1 = " << relpos1 <<
", p2 = " << relpos2 <<
", norm = " << relnorm <<
", depth = " << depth << endl;
104 static fVec3 vel1, vel2, relvel, slipvel;
107 vel2.
cross(rjoint_ang_vel, relpos2-rjoint_pos);
108 vel2 += rjoint_lin_vel;
110 update_log <<
"vel1 = " << vel1 << endl;
111 update_log <<
"vel2 = " << vel2 << endl;
113 relvel.
sub(vel2, vel1);
115 slipvel -= (relnorm*relvel)*relnorm;
117 update_log <<
"relvel = " << relvel << endl;
121 relvel -= (0.005*depth/timestep)*relnorm;
125 double abs_slipvel = slipvel.
length();
129 if(abs_slipvel > 1e-6)
138 slipvel -= (relnorm*tmp)*relnorm;
139 abs_slipvel = slipvel.
length();
140 if(abs_slipvel > 1e-6)
147 tmp(0) = 0.0; tmp(1) = 1.0; tmp(2) = 0.0;
149 slipvel -= (relnorm*tmp)*relnorm;
150 abs_slipvel = slipvel.
length();
156 ratt(0,0) =
x(0); ratt(0,1) =
y(0); ratt(0,2) = z(0);
157 ratt(1,0) =
x(1); ratt(1,1) =
y(1); ratt(1,2) = z(1);
158 ratt(2,0) =
x(2); ratt(2,1) =
y(2); ratt(2,2) = z(2);
160 static fVec3 relpos2_r;
162 temp.
sub(relpos2, rjoint_pos);
163 relpos2_r.
mul(t_rjoint_att, temp);
164 ratt_r.
mul(t_rjoint_att, ratt);
165 pair_positions.push_back(relpos2);
166 pair_normals.push_back(relnorm);
167 pair_relvels.push_back(relvel);
171 pair_orientations.push_back(ratt);
172 pair_positions_real.push_back(relpos2_r);
173 pair_orientations_real.push_back(ratt_r);
174 static fVec3 omega_x_p, omega_x_omega_x_p, jdot;
177 jdot.
mul(omega_x_omega_x_p, ratt);
178 pair_jdot.push_back(jdot);
179 omega_x_p.
cross(rjoint_ang_vel, relpos2);
180 omega_x_omega_x_p.
cross(rjoint_ang_vel, omega_x_p);
181 jdot.
mul(omega_x_omega_x_p, ratt);
182 pair_jdot_real.push_back(jdot);
186 int n_valid_points = pair_relvels.size();
187 if(n_valid_points == 0)
continue;
188 static char jname[256];
191 main_vjoint->
real = rjoint;
193 static fVec3 pjoint_pos;
195 pjoint_att.
tran(rjoint_att);
196 pjoint_pos.
mul(pjoint_att, rjoint_pos);
202 std::vector<int> add;
203 add.resize(n_valid_points);
204 double min_distance = 1.0e-3;
205 for(
int m=0; m<n_valid_points; m++)
208 fVec3& posm = pair_positions[m];
209 for(
int n=0;
n<m;
n++)
211 if(!add[
n])
continue;
212 fVec3& posn = pair_positions[
n];
217 if(len < min_distance)
220 update_log <<
" " << m <<
": too close: " << len << endl;
227 for(
int m=0; m<n_valid_points; m++)
229 if(!add[m])
continue;
230 fVec3& posm = pair_positions[m];
231 static fVec3 first_vec;
232 double min_angle=0.0, max_angle=0.0;
233 int have_first_vec =
false;
234 for(
int n=0;
n<n_valid_points;
n++)
236 if(
n == m || !add[
n])
continue;
237 fVec3& posn = pair_positions[
n];
246 have_first_vec =
true;
253 double cs = first_vec * pp;
254 fcp.
cross(first_vec, pp);
256 if(fcp * norm < 0.0) ss *= -1.0;
257 double angle = atan2(ss, cs);
258 if(angle < min_angle) min_angle = angle;
259 if(angle > max_angle) max_angle = angle;
260 if(max_angle - min_angle >=
PI)
263 update_log <<
" inside: " << max_angle <<
", " << min_angle << endl;
270 for(
int m=0; m<n_valid_points; m++)
273 update_log <<
"check[" << m <<
"]: pos = " << pair_positions[m] <<
", add = " << add[m] << endl;
277 static fVec3 loc_relvel;
279 loc_relvel.
mul(pair_relvels[m], pair_orientations[m]);
283 static fMat Jv(3,6), Jr(3,6);
284 static fMat33 Pcross, RtPx;
285 fVec3& rpos = pair_positions[m];
287 t_ratt.
tran(pair_orientations[m]);
289 RtPx.
mul(t_ratt, Pcross);
290 Jv(0,0) = t_ratt(0,0);
291 Jv(0,1) = t_ratt(0,1);
292 Jv(0,2) = t_ratt(0,2);
293 Jv(1,0) = t_ratt(1,0);
294 Jv(1,1) = t_ratt(1,1);
295 Jv(1,2) = t_ratt(1,2);
296 Jv(2,0) = t_ratt(2,0);
297 Jv(2,1) = t_ratt(2,1);
298 Jv(2,2) = t_ratt(2,2);
299 Jv(0,3) = -RtPx(0,0);
300 Jv(0,4) = -RtPx(0,1);
301 Jv(0,5) = -RtPx(0,2);
302 Jv(1,3) = -RtPx(1,0);
303 Jv(1,4) = -RtPx(1,1);
304 Jv(1,5) = -RtPx(1,2);
305 Jv(2,3) = -RtPx(2,0);
306 Jv(2,4) = -RtPx(2,1);
307 Jv(2,5) = -RtPx(2,2);
313 rpos = pair_positions_real[m];
314 t_ratt.
tran(pair_orientations_real[m]);
316 RtPx.
mul(t_ratt, Pcross);
317 Jr(0,0) = t_ratt(0,0);
318 Jr(0,1) = t_ratt(0,1);
319 Jr(0,2) = t_ratt(0,2);
320 Jr(1,0) = t_ratt(1,0);
321 Jr(1,1) = t_ratt(1,1);
322 Jr(1,2) = t_ratt(1,2);
323 Jr(2,0) = t_ratt(2,0);
324 Jr(2,1) = t_ratt(2,1);
325 Jr(2,2) = t_ratt(2,2);
326 Jr(0,3) = -RtPx(0,0);
327 Jr(0,4) = -RtPx(0,1);
328 Jr(0,5) = -RtPx(0,2);
329 Jr(1,3) = -RtPx(1,0);
330 Jr(1,4) = -RtPx(1,1);
331 Jr(1,5) = -RtPx(1,2);
332 Jr(2,3) = -RtPx(2,0);
333 Jr(2,4) = -RtPx(2,1);
334 Jr(2,5) = -RtPx(2,2);
351 if(n_total_points == 0)
380 for(
int i=0;
i<n_outer_joints;
i++)
382 outer_joints[
i]->f_final.zero();
390 int n_contacts_3 = 3*n_contacts;
392 fMat Phi_hat(n_contacts_3, n_contacts_3);
393 fVec bias_hat(n_contacts_3);
397 for(
int i=0;
i<n_contacts;
i++)
402 bias_hat(index) = v(0);
403 bias_hat(index+1) = v(1);
404 bias_hat(index+2) = v(2);
407 std::vector<int> r_index;
408 std::vector<int> v_index;
409 r_index.resize(n_contacts);
410 v_index.resize(n_contacts);
411 for(
int i=0;
i<n_contacts;
i++)
414 for(
int j=0; j<n_outer_joints; j++)
427 for(
int i=0;
i<n_contacts;
i++)
431 static fVec dacc_r(3), dacc_v(3);
445 bias_hat(i3) += dacc_r(0);
446 bias_hat(i3+1) += dacc_r(1);
447 bias_hat(i3+2) += dacc_r(2);
452 for(
int j=0; j<n_contacts; j++)
455 static fMat PJ(6,3), JPJ(3,3), L(3,3);
457 PJ.mul(Lambda[r_index[i]][r_index[j]],
tran(
sim->
all_Jv[j]));
479 static fMat Lsub(3,3);
481 update_log <<
"Phi_hat[" << i <<
"][" << j <<
"] = " << Lsub << endl;
483 Lsub.
get_submat(0, 0, Lambda[r_index[i]][r_index[j]]);
484 update_log <<
"L[" << r_index[
i] <<
"][" << r_index[j] <<
"] = " << Lsub << endl;
485 Lsub.
get_submat(0, 0, Lambda[v_index[i]][r_index[j]]);
486 update_log <<
"L[" << v_index[
i] <<
"][" << r_index[j] <<
"] = " << Lsub << endl;
487 Lsub.
get_submat(0, 0, Lambda[r_index[i]][v_index[j]]);
488 update_log <<
"L[" << r_index[
i] <<
"][" << v_index[j] <<
"] = " << Lsub << endl;
489 Lsub.
get_submat(0, 0, Lambda[v_index[i]][v_index[j]]);
490 update_log <<
"L[" << v_index[
i] <<
"][" << v_index[j] <<
"] = " << Lsub << endl;
501 int n_total_coef = n_coefs*n_contacts + n_contacts;
502 fMat N(n_total_coef, n_total_coef);
505 fMat* Ehat_t =
new fMat [n_contacts];
506 fVec r(n_total_coef);
517 for(
int i=0;
i<n_contacts;
i++)
521 Ehat_t[
i](0,0) = fric_coef;
524 Ehat_t[
i](0, m+1) = -1.0;
529 for(
int i=0;
i<n_contacts;
i++)
531 static fMat N_ij(n_coefs,n_coefs);
532 static fVec r_i(n_coefs);
533 int i3 =
i*3, iN =
i*n_coefs;
535 for(
int j=0; j<n_contacts; j++)
537 static fMat Phi_ij(3,3), CP(n_coefs,3);
538 static fMat B_ij(n_coefs,n_coefs), CinvP(n_coefs, 3);
540 int j3 = j*3, jN = j*(n_coefs);
541 Phi_ij.get_submat(i3, j3, Phi_hat);
547 static fVec bias_i(3);
556 double max_error = 1.0e-3;
558 int max_iteration = 10000;
560 std::vector<int> presolve_g2w;
561 int presolve_failed =
false;
563 presolve_g2w.
resize(n_contacts);
564 for(
int i=0;
i<n_contacts;
i++)
566 presolve_g2w[
i] = -1;
569 fMat Ns(n_contacts, n_contacts);
570 fVec rs(n_contacts), as;
572 for(
int i=0;
i<n_contacts;
i++)
574 rs(
i) = bias_hat(
i*3+2);
575 for(
int j=0; j<n_contacts; j++)
577 Ns(
i, j) = Phi_hat(
i*3+2, j*3+2);
581 presolve_failed = lcp_s.
SolvePivot2(presolve_g2, as, max_error, max_iteration, &n_iteration, presolve_g2w);
584 cerr <<
"presolve_failed (" << n_iteration <<
"/" << max_iteration <<
")" << endl;
585 cerr <<
"Phi_hat = " << Phi_hat << endl;
588 for(
int i=0;
i<n_contacts;
i++)
590 update_log <<
"presolve_g2w[" <<
i <<
"] = " << presolve_g2w[
i] << endl;
593 #ifdef MEASURE_COLLISION_TIME 594 sim->n_total_nodes += n_iteration;
597 #ifdef USE_INITIAL_GUESS 598 std::vector<int> w2a, w2g, z2a, z2g;
601 std::vector<int> active2all;
609 for(
int i=0;
i<n_contacts;
i++)
611 if(presolve_g2w[
i] >= 0)
613 active2all.push_back(
i);
620 for(
int i=0;
i<n_contacts;
i++)
622 active2all.push_back(
i);
626 update_log <<
"*** start searching constraint set" << endl;
628 int max_global_iteration = 1;
630 while(count < max_global_iteration)
632 std::vector<int> all2active;
633 std::vector<int> g2w;
634 all2active.
resize(n_contacts);
635 for(
int i=0;
i<n_contacts;
i++)
641 int n_active_contacts = active2all.size();
642 if(n_active_contacts > 0)
644 int n_active_coef = n_active_contacts*n_coefs + n_active_contacts;
645 N_active.
resize(n_active_coef, n_active_coef);
646 r_active.
resize(n_active_coef);
649 for(
int i=0;
i<n_active_contacts;
i++)
651 all2active[active2all[
i]] =
i;
654 update_log <<
"n_active_contacts = " << n_active_contacts << endl;
655 update_log <<
"n_active_coef = " << n_active_coef << endl;
657 for(
int i=0;
i<n_active_contacts;
i++)
659 static fMat N_ij(n_coefs,n_coefs);
660 static fVec r_i(n_coefs);
661 int i_active_N =
i*n_coefs;
662 int i_all = active2all[
i];
663 int i_all_N = i_all*n_coefs;
664 for(
int j=0; j<n_active_contacts; j++)
666 int j_all = active2all[j];
667 int j_all_N = j_all*n_coefs;
668 int j_active_N = j*n_coefs;
670 N_active.
set_submat(i_active_N, j_active_N, N_ij);
674 N_active.
set_submat(i_active_N, n_coefs*n_active_contacts+
i, E);
675 N_active.
set_submat(n_coefs*n_active_contacts+
i, i_active_N, Ehat_t[
i]);
677 #ifdef USE_INITIAL_GUESS 680 N_init.
resize(n_active_coef, n_active_coef);
681 r_init.
resize(n_active_coef);
682 w2a.resize(n_active_coef);
683 w2g.resize(n_active_coef);
684 z2a.resize(n_active_coef);
685 z2g.resize(n_active_coef);
686 for(
int i=0;
i<n_active_coef;
i++)
693 for(
int i=0;
i<n_active_contacts;
i++)
701 LCP::Pivot(w2a, w2g, z2a, z2g, N_active, r_active, N_init, r_init);
702 N_active.
set(N_init);
703 r_active.
set(r_init);
705 LCP lcp(N_active, r_active);
709 g2w.resize(n_active_coef);
710 #ifdef MEASURE_COLLISION_TIME 711 sim->n_total_contacts += n_contacts;
712 sim->n_active_contacts += n_active_contacts;
713 LongInteger t1 = GetTick();
715 #ifdef USE_NORMAL_LEMKE 716 int failed = lcp.
SolvePivot(g2, a, max_error, max_iteration, &n_iteration, g2w);
718 int failed = lcp.
SolvePivot2(g2, a, max_error, max_iteration, &n_iteration, g2w);
721 #ifdef MEASURE_COLLISION_TIME 722 LongInteger t2 = GetTick();
723 sim->lcp_solve_time += ExpiredTime(t1, t2);
724 sim->n_total_nodes += n_iteration;
729 update_log <<
"n_iteration = " << n_iteration << endl;
732 error.
mul(N_active, g2);
736 update_log <<
"error = " << error.
length() << endl;
738 if(error.
length() > 1e-4) failed =
true;
741 cerr <<
"failed (" << n_iteration <<
"/" << max_iteration <<
"): n_contacts = " << n_contacts << endl;
742 #ifdef MEASURE_COLLISION_TIME 743 sim->n_failure_frames++;
746 update_log <<
"failed" << endl;
750 cerr <<
"using presolve result" << endl;
751 for(
int i=0;
i<n_contacts;
i++)
753 fk[
i](2) = presolve_g2(
i);
761 update_log <<
"success" << endl;
762 update_log <<
"g2 = " <<
tran(g2) << endl;
763 update_log <<
"a = " <<
tran(a) << endl;
764 update_log <<
"g2w = " << endl;
765 for(
int i=0;
i<n_active_contacts;
i++)
767 update_log <<
"active contact[" <<
i <<
"] a = " << flush;
768 for(
int j=0; j<n_coefs; j++)
770 update_log << g2w[
i*n_coefs+j] <<
" " << flush;
774 for(
int i=0;
i<n_active_contacts;
i++)
776 update_log <<
"active contact[" <<
i <<
"] lambda = " << g2w[n_active_contacts*n_coefs+
i] << endl;
779 #ifdef USE_INITIAL_GUESS 780 for(
int i=0;
i<n_active_coef;
i++)
788 for(
int i=0;
i<n_active_contacts;
i++)
790 static fVec g2_i(n_coefs);
793 fk[active2all[
i]].
mul(Ck, g2_i);
795 update_log <<
"fk[" << active2all[
i] <<
"] = " <<
tran(fk[active2all[
i]]) << endl;
802 for(
int i=0;
i<n_contacts;
i++)
807 int constraint_modified =
false;
808 for(
int i=0;
i<n_contacts;
i++)
810 static fVec bias_i(3);
812 for(
int j=0; j<n_contacts; j++)
814 static fMat Phi_ij(3,3);
816 vk[
i] += Phi_ij * fk[j];
820 update_log <<
"vk[" <<
i <<
"] = " <<
tran(vk[
i]) << endl;
821 if(vk[i](2) < -max_error)
823 update_log <<
"--- too small vertical velocity" << endl;
826 #ifdef USE_INITIAL_GUESS 827 if((all2active[i] >= 0 && w2g[all2active[i]*n_coefs] < 0 && g2w[all2active[i]*n_coefs] >= 0) ||
828 (all2active[i] >= 0 && w2g[all2active[i]*n_coefs] >= 0 && g2w[all2active[i]*n_coefs] < 0) ||
830 if((all2active[i] >= 0 && g2w[all2active[i]*n_coefs] >= 0) ||
832 vk[i](2) < -max_error)
834 active2all.push_back(i);
836 update_log <<
"added to active" << endl;
838 if(vk[i](2) < -max_error)
840 constraint_modified =
true;
842 update_log <<
"constraint modified" << endl;
848 #ifdef USE_INITIAL_GUESS 849 if((all2active[i] >= 0 && w2g[all2active[i]*n_coefs] < 0 && g2w[all2active[i]*n_coefs] >= 0) ||
850 (all2active[i] >= 0 && w2g[all2active[i]*n_coefs] >= 0 && g2w[all2active[i]*n_coefs] < 0))
852 if(all2active[i] >= 0 && g2w[all2active[i]*n_coefs] >= 0)
855 update_log <<
"removed from active" << endl;
859 if(!constraint_modified)
break;
862 update_log <<
"end of search" << endl;
866 for(
int i=0;
i<n_outer_joints;
i++)
868 outer_joints[
i]->f_final.zero();
870 for(
int i=0;
i<n_contacts;
i++)
872 static fVec3 f, f_virt, f_real, moment;
876 Joint* r_joint = outer_joints[r_index[
i]]->joint;
877 Joint* v_joint = outer_joints[v_index[
i]]->joint;
880 r_joint->real->ext_force(0) += f0(0);
881 r_joint->real->ext_force(1) += f0(1);
882 r_joint->real->ext_force(2) += f0(2);
883 r_joint->real->ext_moment(0) += f0(3);
884 r_joint->real->ext_moment(1) += f0(4);
885 r_joint->real->ext_moment(2) += f0(5);
893 outer_joints[r_index[
i]]->f_final += f0;
894 outer_joints[v_index[
i]]->f_final -= f0;
896 update_log << r_joint->real->name <<
" force/moment: " << r_joint->real->ext_force << r_joint->real->ext_moment << endl;
virtual int clear_contact()
fVec3 loc_lin_vel
linear velocity in local frame
fVec3 cone_dir[N_FRIC_CONE_DIV]
joint_list contact_vjoints
void set_subvec(int start, const fVec &subV)
Copy a smaller vector as a sub-vector.
int resize(int i, int j)
Changes the matrix size.
friend fVec3 unit(const fVec3 &v)
Returns the unit vector with the same direction (with length check)
void set(const fMat33 &mat)
Copies a matrix.
void mul(const fMat33 &mat1, const fMat33 &mat2)
friend fMat33 tran(const fMat33 &m)
Returns the transpose.
int in_create_chain
true if between BeginCreateChain() and EndCreateChain().
void cross(const fVec3 &vec1, const fVec3 &vec2)
Cross product.
fVec3 rpos_real
relative position in the real joint frame
Forward dynamics computation based on Assembly-Disassembly Algorithm.
fVec3 loc_ang_vel
angular velocity in local frame
static void Pivot(int idx1, int idx2, const fMat &M, const fVec &q, fMat &M_new, fVec &q_new)
void error(char *msg) const
int Update()
Compute joint accelerations.
void set(double *v)
Set element values from array or three values.
void mul(const fMat &mat1, const fMat &mat2)
void zero()
Creates a zero matrix.
void CalcPosition()
Forward kinematics.
void set(double *_d)
Sets all elements.
int SolvePivot(fVec &g, fVec &a, double _max_error, int _max_iteration, int *n_iteration, std::vector< int > &_g2w)
Solve using Lemke's method.
void mul(const fVec &vec, double d)
std::vector< fVec3 > all_jdot_r
Solves a Linear Complementarity Problem (LCP)
fVec3 ext_force
external force
fMat33 abs_att
absolute orientation
std::vector< fVec3 > contact_relvels
void get_submat(int row_start, int col_start, const fMat &allM)
Extract a sub-matrix and set to myself.
void get_subvec(int start, const fVec &allV)
Copy a sub-vector of a larger vector.
void cross(const fVec3 &p)
Sets spectial matrices.
char * name
joint name (including the character name)
std::vector< fVec3 > all_jdot_v
void resize(int i)
Change the size.
int AddJoint(Joint *target, Joint *p)
Add a new joint target as a child of joint p.
fMat33 ratt_real
relative orientation in the real joint frame
fMat tran(const fMat &mat)
int calc_contact_force(double timestep)
void zero()
Creates a zero vector.
std::string sprintf(char const *__restrict fmt,...)
void set_submat(int row_start, int col_start, const fMat &subM)
Sets a sub-matrix of myself.
void sub(const fVec3 &vec1, const fVec3 &vec2)
friend double length(const fVec3 &v)
Returns the length of a vector.
std::vector< double > fric_coefs
void set(double *_d)
Sets the values from an array.
int SolvePivot2(fVec &g, fVec &a, double _max_error, int _max_iteration, int *n_iteration, std::vector< int > &_g2w)
Solve by pivot using path planning algorithm.
fVec3 ext_moment
external moment around the local frame
friend double length(const fVec &v)
Length of the vector.
fVec3 abs_pos
absolute position
void mul(const fVec3 &vec, double d)
#define N_FRIC_CONE_DIV
Number of vertices of the friction cone approximation.
int ClearExtForce()
Clear the external forces/torques.
The class for representing a joint.
Joint * real
pointer to the real (connected) joint; for closed chains.
int i_joint
index of the joint
std::vector< fMat > all_Jr
std::vector< fMat > all_Jv
Joint * parent
pointer to the parent joint
Matrix of generic size. The elements are stored in a one-dimensional array in row-major order...