00001
00002
00003
00004
00005
00006
00007
00008
00014
00015
00016 #include "sdcontact.h"
00017
00018 #include <fstream>
00019
00020 static ofstream sd_log;
00021
00022 int SDContactPair::Update(double timestep, int n_contact, double** coords, double** normals, double* depths)
00023 {
00024 sd_log << "Update(" << n_contact << ")" << endl;
00025 in_slip = false;
00026 if(n_contact > 0)
00027 {
00028 int i;
00029 if(!init_set) set_init();
00030 for(i=0; i<n_contact; i++)
00031 update(timestep, n_contact, coords[i], normals[i], depths[i]);
00032 if(in_slip) init_set = false;
00033 }
00034 else
00035 {
00036 init_set = false;
00037 }
00038 sd_log << "end Update" << endl;
00039 return 0;
00040 }
00041
00042 int SDContactPair::set_init()
00043 {
00044 init_set = true;
00045 Joint* joint1 = joints[0];
00046 Joint* joint2 = joints[1];
00047 static fVec3 pp;
00048 static fMat33 tr;
00049
00050 pp.sub(joint2->abs_pos, joint1->abs_pos);
00051 tr.tran(joint1->abs_att);
00052 init_pos.mul(tr, pp);
00053 init_att.mul(tr, joint2->abs_att);
00054 return 0;
00055 }
00056
00057 static double slip_func(double c, double v)
00058 {
00059 return (1.0 - exp(-c*v));
00060 }
00061
00062 int SDContactPair::update(double timestep, int n_contact, double* coord, double* normal, double depth)
00063 {
00064 Joint* joint1 = joints[0];
00065 Joint* joint2 = joints[1];
00066 static fVec3 relpos1, relpos2;
00067 static fVec3 relnorm;
00068 relpos1(0) = coord[0];
00069 relpos1(1) = coord[1];
00070 relpos1(2) = coord[2];
00071 relpos2(0) = coord[0];
00072 relpos2(1) = coord[1];
00073 relpos2(2) = coord[2];
00074 relnorm(0) = normal[0];
00075 relnorm(1) = normal[1];
00076 relnorm(2) = normal[2];
00077 sd_log << "relpos1 = " << relpos1 << endl;
00078 sd_log << "relnorm = " << relnorm << endl;
00079
00080 static fVec3 vel, vel1, vel2, force, tmp;
00081 double d, v, f;
00082
00083 vel1.cross(joint1->loc_ang_vel, relpos1);
00084 vel1 += joint1->loc_lin_vel;
00085
00086 static fVec3 rpos2, pp, lin2, ang2;
00087 static fMat33 ratt2, tr;
00088 pp.sub(joint2->abs_pos, joint1->abs_pos);
00089 tr.tran(joint1->abs_att);
00090
00091 rpos2.mul(tr, pp);
00092 ratt2.mul(tr, joint2->abs_att);
00093
00094 lin2.mul(ratt2, joint2->loc_lin_vel);
00095 ang2.mul(ratt2, joint2->loc_ang_vel);
00096
00097 relpos2 -= rpos2;
00098
00099 vel2.cross(ang2, relpos2);
00100 vel2 += lin2;
00101
00102 vel.sub(vel1, vel2);
00103 v = relnorm * vel;
00104 d = depth;
00105 sd_log << "depth = " << depth << endl;
00106 sd_log << "vel1 = " << vel1 << endl;
00107 sd_log << "joint2->loc_lin_vel = " << joint2->loc_lin_vel << endl;
00108 sd_log << "vel2 = " << vel2 << endl;
00109 sd_log << "vel = " << vel << endl;
00110
00111
00112
00113 #ifdef SD_NONLINEAR
00114 f = (spring + damper * v) * d;
00115 #else
00116 f = (spring * d + damper * v);
00117 #endif
00118 if(f < 0.0) return 0;
00119 force.mul(f, relnorm);
00120
00121
00122
00123
00124 static fVec3 slip_vel;
00125 double abs_slip, slip_func_coef, w;
00126 slip_vel.mul(v, relnorm);
00127 slip_vel -= vel;
00128 abs_slip = slip_vel.length();
00129 slip_func_coef = slip_func_coef_base / timestep;
00130 w = slip_func(slip_func_coef, abs_slip);
00131
00132 static fVec3 p_init;
00133
00134
00135 p_init.add(init_pos, relpos2);
00136
00137 static fVec3 tmp_fric;
00138 tmp_fric.sub(init_pos, relpos2);
00139 tmp_fric -= rpos2;
00140 tmp_fric *= slip_p;
00141 tmp.mul(-slip_d, slip_vel);
00142 tmp_fric += tmp;
00143
00144 double _t = tmp_fric * relnorm;
00145 tmp.mul(_t, relnorm);
00146 tmp_fric -= tmp;
00147
00148
00149 double abs_fric = tmp_fric.length();
00150
00151 #ifdef USE_SLIP_FUNC
00152 if(abs_fric > f*static_fric)
00153 {
00154
00155
00156 double tiny = 1e-8, _c;
00157 if(abs_slip > tiny)
00158 _c = slip_fric * f * w / abs_slip;
00159 else
00160 _c = slip_fric * f * slip_func_coef;
00161 tmp_fric.mul(-_c, slip_vel);
00162 in_slip = true;
00163 }
00164 #else
00165 double tiny = 1e-8, _c;
00166 #if 1
00167 if(abs_slip > tiny)
00168 {
00169 _c = slip_fric * f / abs_slip;
00170 tmp_fric.mul(-_c, slip_vel);
00171 in_slip = true;
00172 }
00173 else if(abs_fric > f*static_fric)
00174 {
00175
00176 _c = slip_fric * f / abs_fric;
00177 fVec3 fric_save(tmp_fric);
00178 tmp_fric.mul(_c, fric_save);
00179 in_slip = true;
00180 }
00181 #else
00182 if(abs_fric > f*static_fric)
00183 {
00184 if(abs_slip > tiny)
00185 {
00186 _c = slip_fric * f / abs_slip;
00187 tmp_fric.mul(-_c, slip_vel);
00188 in_slip = true;
00189 }
00190 else
00191 {
00192
00193 _c = slip_fric * f / abs_fric;
00194 fVec3 fric_save(tmp_fric);
00195 tmp_fric.mul(_c, fric_save);
00196 in_slip = true;
00197 }
00198 }
00199 #endif
00200 #endif
00201 force += tmp_fric;
00202
00203 force /= (double)n_contact;
00204
00205 static fVec3 m;
00206 joint1->ext_force -= force;
00207 m.cross(relpos1, force);
00208 joint1->ext_moment -= m;
00209
00210
00211
00212
00213
00214
00215 tmp.mul(force, ratt2);
00216 sd_log << "ext_force = " << tmp << endl;
00217 joint2->ext_force += tmp;
00218 m.cross(relpos2, force);
00219 tmp.mul(m, ratt2);
00220 joint2->ext_moment += tmp;
00221 sd_log << "ext_moment = " << tmp << endl;
00222 return 0;
00223 }
00224