示例#1
0
void IK_QElbowSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta)
{
	if (dof == 0) {
		m_locked[0] = true;
		jacobian.Lock(m_DoF_id, delta[0]);
	}
	else {
		m_locked[1] = true;
		jacobian.Lock(m_DoF_id+1, delta[1]);
	}
}
示例#2
0
void IK_QSphericalSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta)
{
	if (dof == 1) {
		m_locked[1] = true;
		jacobian.Lock(m_DoF_id+1, delta[1]);
	}
	else {
		m_locked[0] = m_locked[2] = true;
		jacobian.Lock(m_DoF_id, delta[0]);
		jacobian.Lock(m_DoF_id+2, delta[2]);
	}
}
示例#3
0
void IK_QJacobian::SubTask(IK_QJacobian& jacobian)
{
	if (!ComputeNullProjection())
		return;

	// restrict lower priority jacobian
	jacobian.Restrict(m_d_theta, m_null);

	// add angle update from lower priority
	jacobian.Invert();

	// note: now damps secondary angles with minimum damping value from
	// SDLS, to avoid shaking when the primary task is near singularities,
	// doesn't work well at all
	int i;
	for (i = 0; i < m_d_theta.size(); i++)
		m_d_theta[i] = m_d_theta[i] + /*m_min_damp**/jacobian.AngleUpdate(i);
}
示例#4
0
bool IK_QElbowSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp)
{
	if (m_locked[0] && m_locked[1])
		return false;

	clamp[0] = clamp[1] = false;

	if (!m_locked[0]) {
		m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);

		if (m_limit) {
			if (m_new_angle > m_max) {
				delta[0] = m_max - m_angle;
				m_new_angle = m_max;
				clamp[0] = true;
			}
			else if (m_new_angle < m_min) {
				delta[0] = m_min - m_angle;
				m_new_angle = m_min;
				clamp[0] = true;
			}
		}
	}

	if (!m_locked[1]) {
		m_new_twist = m_twist + jacobian.AngleUpdate(m_DoF_id+1);

		if (m_limit_twist) {
			if (m_new_twist > m_max_twist) {
				delta[1] = m_max_twist - m_twist;
				m_new_twist = m_max_twist;
				clamp[1] = true;
			}
			else if (m_new_twist < m_min_twist) {
				delta[1] = m_min_twist - m_twist;
				m_new_twist = m_min_twist;
				clamp[1] = true;
			}
		}
	}

	return (clamp[0] || clamp[1]);
}
示例#5
0
bool IK_QTranslateSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp)
{
	int dof_id = m_DoF_id, dof = 0, i, clamped = false;

	MT_Vector3 dx(0.0, 0.0, 0.0);

	for (i = 0; i < 3; i++) {
		if (!m_axis_enabled[i]) {
			m_new_translation[i] = m_translation[i];
			continue;
		}

		clamp[dof] = false;

		if (!m_locked[dof]) {
			m_new_translation[i] = m_translation[i] + jacobian.AngleUpdate(dof_id);

			if (m_limit[i]) {
				if (m_new_translation[i] > m_max[i]) {
					delta[dof] = m_max[i] - m_translation[i];
					m_new_translation[i] = m_max[i];
					clamped = clamp[dof] = true;
				}
				else if (m_new_translation[i] < m_min[i]) {
					delta[dof] = m_min[i] - m_translation[i];
					m_new_translation[i] = m_min[i];
					clamped = clamp[dof] = true;
				}
			}
		}

		dof_id++;
		dof++;
	}

	return clamped;
}
示例#6
0
bool IK_QRevoluteSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp)
{
	if (m_locked[0])
		return false;

	m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);

	clamp[0] = false;

	if (m_limit == false)
		return false;

	if (m_new_angle > m_max)
		delta[0] = m_max - m_angle;
	else if (m_new_angle < m_min)
		delta[0] = m_min - m_angle;
	else
		return false;
	
	clamp[0] = true;
	m_new_angle = m_angle + delta[0];

	return true;
}
示例#7
0
void IK_QSwingSegment::Lock(int, IK_QJacobian& jacobian, MT_Vector3& delta)
{
	m_locked[0] = m_locked[1] = true;
	jacobian.Lock(m_DoF_id, delta[0]);
	jacobian.Lock(m_DoF_id+1, delta[1]);
}
示例#8
0
bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp)
{
	if (m_locked[0] && m_locked[1])
		return false;

	MT_Vector3 dq;
	dq.x() = jacobian.AngleUpdate(m_DoF_id);
	dq.y() = 0.0;
	dq.z() = jacobian.AngleUpdate(m_DoF_id+1);

	// Directly update the rotation matrix, with Rodrigues' rotation formula,
	// to avoid singularities and allow smooth integration.

	MT_Scalar theta = dq.length();

	if (!MT_fuzzyZero(theta)) {
		MT_Vector3 w = dq*(1.0/theta);

		MT_Scalar sine = sin(theta);
		MT_Scalar cosine = cos(theta);
		MT_Scalar cosineInv = 1-cosine;

		MT_Scalar xsine = w.x()*sine;
		MT_Scalar zsine = w.z()*sine;

		MT_Scalar xxcosine = w.x()*w.x()*cosineInv;
		MT_Scalar xzcosine = w.x()*w.z()*cosineInv;
		MT_Scalar zzcosine = w.z()*w.z()*cosineInv;

		MT_Matrix3x3 M(
			cosine + xxcosine, -zsine, xzcosine,
			zsine, cosine, -xsine,
			xzcosine, xsine, cosine + zzcosine);

		m_new_basis = m_basis*M;

		RemoveTwist(m_new_basis);
	}
	else
		m_new_basis = m_basis;

	if (m_limit_x == false && m_limit_z == false)
		return false;

	MT_Vector3 a = SphericalRangeParameters(m_new_basis);
	MT_Scalar ax = 0, az = 0;

	clamp[0] = clamp[1] = false;
	
	if (m_limit_x && m_limit_z) {
		ax = a.x();
		az = a.z();

		if (EllipseClamp(ax, az, m_min, m_max))
			clamp[0] = clamp[1] = true;
	}
	else if (m_limit_x) {
		if (ax < m_min[0]) {
			ax = m_min[0];
			clamp[0] = true;
		}
		else if (ax > m_max[0]) {
			ax = m_max[0];
			clamp[0] = true;
		}
	}
	else if (m_limit_z) {
		if (az < m_min[1]) {
			az = m_min[1];
			clamp[1] = true;
		}
		else if (az > m_max[1]) {
			az = m_max[1];
			clamp[1] = true;
		}
	}

	if (clamp[0] == false && clamp[1] == false)
		return false;

	m_new_basis = ComputeSwingMatrix(ax, az);

	delta = MatrixToAxisAngle(m_basis.transposed()*m_new_basis);
	delta[1] = delta[2]; delta[2] = 0.0;

	return true;
}
示例#9
0
void IK_QRevoluteSegment::Lock(int, IK_QJacobian& jacobian, MT_Vector3& delta)
{
	m_locked[0] = true;
	jacobian.Lock(m_DoF_id, delta[0]);
}
示例#10
0
void IK_QTranslateSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta)
{
	m_locked[dof] = true;
	jacobian.Lock(m_DoF_id+dof, delta[dof]);
}