12. 摩 擦
ODE (Open Dynamics Engine) åˆç´šè¬›åº§ã®ç¬¬ï¼‘2回目ã§ã™ã€‚
ä»Šå›žã¯æ‘©æ“¦ã«ã¤ã„ã¦èª¬æ˜Žã—ã¾ã™ã€‚摩擦ã«ã¤ã„ã¦ã¯é«˜æ ¡ã§ç¿’ã£ãŸã¨æ€ã„ã¾ã™ã€‚fNを法線方å‘ã€fTを接線方å‘ã®åŠ›ãƒ™ã‚¯ãƒˆãƒ«ã€Î¼ã‚’摩擦係数ã¨ã™ã‚‹ã¨ä»¥ä¸‹ã®å…¬å¼ãŒæˆã‚Šç«‹ã¡ã¾ã™ã€‚
|fT| <= μ |fN|
接触é¢ã®æ–¹å‘ã«ã‚ˆã‚‰ãšä¸Šã®å¼ãŒæˆã‚Šç«‹ã¤å ´åˆã¯ã€ä¸Šã®ä¸ç‰å¼ã¯ã€å††éŒã®è»¸ãŒfNã§ã€æŽ¥è§¦ç‚¹ãŒé ‚ç‚¹ã®æ‘©æ“¦å††éŒã¨ãªã‚Šã¾ã™ã€‚ fNã¨fTã®åˆåŠ›ã§ã‚ã‚‹æ‘©æ“¦åŠ›ãƒ™ã‚¯ãƒˆãƒ«ãŒæ‘©æ“¦å††éŒå†…ã«ã‚ã‚Œã°æ»‘りã¯ç™ºç”Ÿã—ã¾ã›ã‚“ãŒã€å¤–ã«å‡ºã‚‹ã¨æ»‘り出ã™ã“ã¨ã«ãªã‚Šã¾ã™ã€‚
ODEã®æ‘©æ“¦ãƒ¢ãƒ‡ãƒ«ã¯ã‚¯ãƒ¼ãƒãƒ³æ‘©æ“¦ãƒ¢ãƒ‡ãƒ«ã®è¿‘ä¼¼ã§ã™ã€‚高速化ã®ãŸã‚ã«æ‘©æ“¦å††éŒã‚’次ã®ï¼’通りã®ãƒ¢ãƒ‡ãƒ«ã§è¿‘ä¼¼ã—ã¦ã„ã¾ã™ã€‚特ã«è¨å®šã—ãªã„å ´åˆã¯ã€æœ€ã‚‚å˜ç´”ãªæœ€å¤§æ‘©æ“¦åŠ›è¿‘ä¼¼ã¨ãªã‚Šã¾ã™ã€‚摩擦ãŒã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«é‡è¦ãªå½±éŸ¿ã‚’åŠã¼ã™å ´åˆã¯æ‘©æ“¦å››è§’éŒ˜è¿‘ä¼¼ã‚’é¸æŠžã—ã¦ãã ã•ã„。ãªãŠã€ODEã§ã¯é™æ¢æ‘©æ“¦ä¿‚æ•°ã€å‹•摩擦係数ã®åŒºåˆ¥ã¯ã‚りã¾ã›ã‚“。
1. 最大摩擦力近似 (constant force limit)
摩擦係数μを接触点ã«ãŠã‘る接線方å‘ã®æœ€å¤§æ‘©æ“¦åŠ›ã¨è¿‘ä¼¼ã™ã‚‹ã€‚ã¤ã¾ã‚Šã€æ³•ç·šæ–¹å‘ã®åŠ›ã‚’è€ƒæ…®ã—ãªã„å˜ç´”ãªãƒ¢ãƒ‡ãƒ«ã§ã™ã€‚
2. 摩擦四角錘近似(friction pyramid approximation)
摩擦円éŒã‚’摩擦四角錘ã§è¿‘ä¼¼ã—ã¾ã™ã€‚ã“ã®ãƒ¢ãƒ‡ãƒ«ã‚’é¸æŠžã™ã‚‹ãŸã‚ã«ã¯æŽ¥è§¦ãƒ•ラグã«dContactApprox1ã‚’è¨å®šã—ã¾ã™ã€‚
具体的ãªè¨å®šæ–¹æ³•を以下ã®ãƒ—ãƒã‚°ãƒ©ãƒ ã«ç¤ºã—ã¾ã™ã€‚ï¼‘ï¼—è¡Œç›®ã§æ‘©æ“¦å››è§’錘近似をè¨å®šã™ã‚‹ãŸã‚ã«dContactApprox1ã‚’è¨å®šã—ã¦ã„ã¾ã™ã€‚ã“ã‚ŒãŒæœ‰åйã«ãªã‚‹ã®ã¯è¡çªã™ã‚‹ã‚¸ã‚ªãƒ¡ãƒˆãƒªãŒbox[0].geomã®å ´åˆã§ã€ãれ以外ã®ã‚¸ã‚ªãƒ¡ãƒˆãƒªã¯æœ€å¤§æ‘©æ“¦åŠ›è¿‘ä¼¼ã¨ãªã‚Šã¾ã™ã€‚
サンプルプãƒã‚°ãƒ©ãƒ ã§ã¯æ–œé¢ã®è§’度を少ã—ãšã¤å¢—åŠ ã•ã›ã€ï¼’ã¤ã®ãƒœãƒƒã‚¯ã‚¹ãŒæ»‘り出ã™è§’度ãŒé•ã†ã“ã¨ãŒã‚ã‹ã‚Šã¾ã™ã€‚摩擦係数を1ã«è¨å®šã—ã¦ã„ã‚‹ãŸã‚ã€ãƒœãƒƒã‚¯ã‚¹ãŒæ»‘り始ã‚る角度ã®ç†è«–値ã¯ï¼”5度ã«ãªã‚Šã¾ã™ã€‚摩擦四角錘近似モデルã®å ´åˆï¼ˆå·¦å´ã®èµ¤ã„ボックス)ã¯ç´„ï¼”ï¼•åº¦ã§æ»‘り出ã—ã¾ã™ãŒã€æœ€å¤§æ‘©æ“¦è¿‘似モデルã§ã¯ãれよりå°ã•ã„è§’åº¦ã§æ»‘り出ã™ã“ã¨ãŒç¢ºèªã§ãã‚‹ã¨æ€ã„ã¾ã™ã€‚
サンプルプãƒã‚°ãƒ©ãƒ ã‚’ã“ã“ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã—ã¦ç¢ºèªã—ã¦ã¿ã¦ãã ã•ã„。
今回ã¯ã“ã“ã¾ã§ã¨ã—ã¾ã™ã€‚
static void nearCallback(void *data, dGeomID o1, dGeomID o2)
{
const int N = 10;
dContact contact[N];
if (((o1 == ground) && (o2 == slope )) || ((o1 == slope) && (o2 == ground))) return;
int isGround = ((ground == o1 || slope == o1) || (ground == o2 || slope == o2)); int n = dCollide(o1, o2, N, &contact[0].geom, sizeof(dContact));
if (isGround) { for (int i = 0; i < n; i++) {
if ((o1 == box[0].geom) || (o2 == box[0].geom)) {
// friciton: friction pyramid model 摩擦四角錘近似
contact[i].surface.mode = dContactApprox1|dContactSoftERP|dContactSoftCFM;
}
else {
// friction: constant force limit model 最大摩擦力近似
contact[i].surface.mode = dContactSoftERP|dContactSoftCFM;
}
contact[i].surface.mu = 1.0; // dInfinity;
contact[i].surface.soft_erp = 1.0; //1.0;
contact[i].surface.soft_cfm = 1e-10;
dJointID c = dJointCreateContact(world, contactgroup, &contact[i]);
dJointAttach(c,dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2));
}
}
}
