242 lines
7.6 KiB
C++
242 lines
7.6 KiB
C++
/*
|
|
* Copyright (C) 2012 Open Source Robotics Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
#include <iostream>
|
|
#include "gazebo/physics/bullet/gzBtUniversalConstraint.hh"
|
|
|
|
#define UNIV_EPS btScalar(0.01f)
|
|
|
|
/////////////////////////////////////////////////
|
|
gzBtUniversalConstraint::gzBtUniversalConstraint(btRigidBody &_rbA,
|
|
btRigidBody &_rbB, const btVector3 &_anchor, const btVector3 &_axis1,
|
|
const btVector3 &_axis2)
|
|
: btGeneric6DofConstraint(_rbA, _rbB, btTransform::getIdentity(),
|
|
btTransform::getIdentity(), true),
|
|
m_anchor(_anchor),
|
|
m_axis1(_axis1),
|
|
m_axis2(_axis2)
|
|
{
|
|
this->maxMotorImpulse[0] = 0;
|
|
this->maxMotorImpulse[1] = 0;
|
|
|
|
// build frame basis
|
|
// 6DOF constraint uses Euler angles and to define limits
|
|
// it is assumed that rotational order is :
|
|
// Z - first, allowed limits are (-PI,PI);
|
|
// new position of Y - second (allowed limits are
|
|
// (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number
|
|
// used to prevent constraint from instability on poles;
|
|
// new position of X, allowed limits are (-PI,PI);
|
|
// So to simulate ODE Universal joint we should use parent
|
|
// axis as Z, child axis as Y and limit all other DOFs
|
|
// Build the frame in world coordinate system first
|
|
btVector3 zAxis = m_axis1.normalize();
|
|
btVector3 yAxis = m_axis2.normalize();
|
|
|
|
// we want right coordinate system
|
|
btVector3 xAxis = yAxis.cross(zAxis);
|
|
btTransform frameInW;
|
|
frameInW.setIdentity();
|
|
frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0],
|
|
xAxis[1], yAxis[1], zAxis[1],
|
|
xAxis[2], yAxis[2], zAxis[2]);
|
|
frameInW.setOrigin(_anchor);
|
|
|
|
// now get constraint frame in local coordinate systems
|
|
m_frameInA = _rbA.getCenterOfMassTransform().inverse() * frameInW;
|
|
m_frameInB = _rbB.getCenterOfMassTransform().inverse() * frameInW;
|
|
|
|
// set limits
|
|
setLinearLowerLimit(btVector3(0., 0., 0.));
|
|
setLinearUpperLimit(btVector3(0., 0., 0.));
|
|
this->setAngularLowerLimit(btVector3(0.f,
|
|
-SIMD_HALF_PI + UNIV_EPS, -SIMD_PI + UNIV_EPS));
|
|
this->setAngularUpperLimit(btVector3(0.f,
|
|
SIMD_HALF_PI - UNIV_EPS, SIMD_PI - UNIV_EPS));
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
gzBtUniversalConstraint::gzBtUniversalConstraint(btRigidBody &_rbB,
|
|
const btVector3 &_anchor, const btVector3 &_axis1, const btVector3 &_axis2)
|
|
: btGeneric6DofConstraint(_rbB, btTransform::getIdentity(), true),
|
|
m_anchor(_anchor),
|
|
m_axis1(_axis1),
|
|
m_axis2(_axis2)
|
|
{
|
|
this->maxMotorImpulse[0] = 0;
|
|
this->maxMotorImpulse[1] = 0;
|
|
|
|
// build frame basis
|
|
// 6DOF constraint uses Euler angles and to define limits
|
|
// it is assumed that rotational order is :
|
|
// Z - first, allowed limits are (-PI,PI);
|
|
// new position of Y - second (allowed limits are
|
|
// (-PI/2 + epsilon, PI/2 - epsilon),
|
|
// where epsilon is a small positive number
|
|
// used to prevent constraint from instability on poles;
|
|
// new position of X, allowed limits are (-PI,PI);
|
|
// So to simulate ODE Universal joint we should use parent axis as Z,
|
|
// child axis as Y and limit all other DOFs
|
|
// Build the frame in world coordinate system first
|
|
btVector3 zAxis = m_axis1.normalize();
|
|
btVector3 yAxis = m_axis2.normalize();
|
|
|
|
// we want right coordinate system
|
|
btVector3 xAxis = yAxis.cross(zAxis);
|
|
|
|
btTransform frameInW;
|
|
frameInW.setIdentity();
|
|
frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0],
|
|
xAxis[1], yAxis[1], zAxis[1],
|
|
xAxis[2], yAxis[2], zAxis[2]);
|
|
frameInW.setOrigin(_anchor);
|
|
|
|
// now get constraint frame in local coordinate systems
|
|
m_frameInA = frameInW;
|
|
m_frameInB = _rbB.getCenterOfMassTransform().inverse() * frameInW;
|
|
|
|
// set limits
|
|
setLinearLowerLimit(btVector3(0., 0., 0.));
|
|
setLinearUpperLimit(btVector3(0., 0., 0.));
|
|
setAngularLowerLimit(btVector3(0.f,
|
|
-SIMD_HALF_PI + UNIV_EPS, -SIMD_PI + UNIV_EPS));
|
|
setAngularUpperLimit(btVector3(0.f,
|
|
SIMD_HALF_PI - UNIV_EPS, SIMD_PI - UNIV_EPS));
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void gzBtUniversalConstraint::setAxis(const btVector3 &_axis1,
|
|
const btVector3 &_axis2)
|
|
{
|
|
m_axis1 = _axis1;
|
|
m_axis2 = _axis2;
|
|
|
|
btVector3 zAxis = _axis1.normalized();
|
|
btVector3 yAxis = _axis2.normalized();
|
|
|
|
// we want right coordinate system
|
|
btVector3 xAxis = yAxis.cross(zAxis);
|
|
|
|
btTransform frameInW;
|
|
frameInW.setIdentity();
|
|
frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0],
|
|
xAxis[1], yAxis[1], zAxis[1],
|
|
xAxis[2], yAxis[2], zAxis[2]);
|
|
frameInW.setOrigin(m_anchor);
|
|
|
|
// now get constraint frame in local coordinate systems
|
|
m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW;
|
|
m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW;
|
|
|
|
this->calculateTransforms();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
const btVector3 &gzBtUniversalConstraint::getAnchor()
|
|
{
|
|
return m_calculatedTransformA.getOrigin();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
const btVector3 &gzBtUniversalConstraint::getAnchor2()
|
|
{
|
|
return m_calculatedTransformB.getOrigin();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
const btVector3 &gzBtUniversalConstraint::getAxis1()
|
|
{
|
|
return m_axis1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
const btVector3 &gzBtUniversalConstraint::getAxis2()
|
|
{
|
|
return m_axis2;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
btScalar gzBtUniversalConstraint::getAngle1()
|
|
{
|
|
this->calculateTransforms();
|
|
return this->getAngle(1);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
btScalar gzBtUniversalConstraint::getAngle2()
|
|
{
|
|
this->calculateTransforms();
|
|
return this->getAngle(2);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void gzBtUniversalConstraint::getUpperLimit(
|
|
btScalar &_ang1max, btScalar &_ang2max)
|
|
{
|
|
btVector3 angles;
|
|
this->getAngularUpperLimit(angles);
|
|
_ang1max = angles.getY();
|
|
_ang2max = angles.getZ();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void gzBtUniversalConstraint::getLowerLimit(
|
|
btScalar &_ang1min, btScalar &_ang2min)
|
|
{
|
|
btVector3 angles;
|
|
this->getAngularLowerLimit(angles);
|
|
_ang1min = angles.getY();
|
|
_ang2min = angles.getZ();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void gzBtUniversalConstraint::setUpperLimit(
|
|
btScalar _ang1max, btScalar _ang2max)
|
|
{
|
|
this->setAngularUpperLimit(btVector3(0.f, _ang1max, _ang2max));
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void gzBtUniversalConstraint::setLowerLimit(
|
|
btScalar _ang1min, btScalar _ang2min)
|
|
{
|
|
this->setAngularLowerLimit(btVector3(0.f, _ang1min, _ang2min));
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
btScalar gzBtUniversalConstraint::getMaxMotorImpulse1() const
|
|
{
|
|
return this->maxMotorImpulse[0];
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
btScalar gzBtUniversalConstraint::getMaxMotorImpulse2() const
|
|
{
|
|
return this->maxMotorImpulse[1];
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void gzBtUniversalConstraint::setMaxMotorImpulse1(btScalar _i)
|
|
{
|
|
this->maxMotorImpulse[0] = _i;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void gzBtUniversalConstraint::setMaxMotorImpulse2(btScalar _i)
|
|
{
|
|
this->maxMotorImpulse[1] = _i;
|
|
}
|