#include "circleJoint.h"
#include <manipulator/ecJointActuator.h>
#include <manipulator/ecManipulatorTokens.h>
#include <foundCore/ecMacros.h>
#include <foundCore/ecMath.h>
#include <math.h>
#include <xmlReaderWriter/ecXmlObjectReaderWriter.h>
#include "circleJointTokens.h"
using
namespace
CircleJointNamespace;
ECXML_DEFINE_TOKENS(CircleJoint, CircleJointNamespace::CircleJointToken)
EcXmlObject* CircleJoint::libraryAttribute()
{
m_LibraryAttribute =
"CircleJoint.ecp"
;
return
&m_LibraryAttribute;
}
CircleJoint::CircleJoint() :
EcLinkKinematics(),
m_Precursor(EcCoordinateSystemTransformation::nullObject()),
m_Radius(3.0),
m_JointValueForStoredTransform(0.0)
{
}
CircleJoint::~CircleJoint() {}
CircleJoint::CircleJoint(
const
CircleJoint& orig) :
EcLinkKinematics(orig),
m_Precursor(orig.m_Precursor),
m_Radius(orig.m_Radius),
m_JointValueForStoredTransform(orig.m_JointValueForStoredTransform)
{}
CircleJoint& CircleJoint::operator=(
const
CircleJoint& orig)
{
if
(
this
== &orig)
{
return
*
this
;
}
EcLinkKinematics::operator=(orig);
m_Precursor = orig.m_Precursor;
m_Radius = orig.m_Radius;
m_JointValueForStoredTransform = orig.m_JointValueForStoredTransform;
return
*
this
;
}
EcBoolean CircleJoint::operator==(
const
CircleJoint& orig)
const
{
EcBoolean retVal = EcLinkKinematics::operator==(orig);
if
(!(m_Precursor == orig.m_Precursor&&
m_Radius == orig.m_Radius
))
{
retVal = EcFalse;
}
return
retVal;
}
EcXmlObject* CircleJoint::creator()
{
EcXmlObject* retVal =
new
CircleJoint();
return
retVal;
}
EcBoolean CircleJoint::xmlInit()
{
return
(EcLinkKinematics::xmlInit());
}
void
CircleJoint::registerComponents()
{
EcLinkKinematics::registerComponents();
registerComponent(CircleJointPrecursor, &m_Precursor);
registerComponent(CircleJointRadiusToken, &m_Radius);
}
const
EcCoordinateSystemTransformation& CircleJoint::precursor()
const
{
return
m_Precursor;
}
void
CircleJoint::setPrecursor(
const
EcCoordinateSystemTransformation& value)
{
m_Precursor = value;
}
EcReal CircleJoint::radius()
const
{
return
m_Radius;
}
void
CircleJoint::setRadius(EcReal radius)
{
m_Radius = radius;
}
const
EcCoordinateSystemTransformation& CircleJoint::calculateTransform
(
EcReal jointValue
)
const
{
m_JointValueForStoredTransform = jointValue;
m_FrameTransform.setToIdentity();
transformBy(m_FrameTransform, m_JointValueForStoredTransform);
return
m_FrameTransform;
}
void
CircleJoint::transformBy
(
EcCoordinateSystemTransformation& xform,
EcReal jointValue
)
const
{
EcOrientation orientation;
EcVector translation;
xform *= precursor();
translation.setX(m_Radius*
cos
(jointValue / m_Radius));
translation.setY(m_Radius*
sin
(jointValue / m_Radius));
translation.setZ(0);
orientation.setFrom123Euler(0, 0, jointValue / m_Radius);
xform.outboardTransformBy(translation, orientation);
}
const
EcGeneralMotion&
CircleJoint::calculateVelocity
(
EcReal jointValue,
EcReal jointVelocity
)
const
{
m_FrameVelocity.setLinearX(-jointVelocity *
sin
(jointValue / m_Radius));
m_FrameVelocity.setLinearY(jointVelocity*
cos
(jointValue / m_Radius));
m_FrameVelocity.setLinearZ(0);
m_FrameVelocity.setAngular(EcVector(0, 0, jointVelocity / m_Radius));
return
m_FrameVelocity;
}
const
EcGeneralAcceleration&
CircleJoint::calculateAcceleration
(
EcReal jointValue,
EcReal jointVelocity,
EcReal jointAcceleration
)
const
{
m_FrameAcceleration.setLinearX(-jointAcceleration *
sin
(jointValue / m_Radius)
-
pow
(jointVelocity, 2) / m_Radius *
cos
(jointValue / m_Radius));
m_FrameAcceleration.setLinearY(jointAcceleration*
cos
(jointValue / m_Radius)
-
pow
(jointVelocity, 2) / m_Radius *
sin
(jointValue / m_Radius));
m_FrameAcceleration.setLinearZ(0);
m_FrameAcceleration.setAngular(EcVector(0, 0, jointAcceleration / m_Radius));
return
m_FrameAcceleration;
}
EcBoolean CircleJoint::approxEq
(
const
CircleJoint& dh2,
EcReal tol
)
const
{
EcBoolean parentAE = EcLinkKinematics::approxEq(dh2, tol);
EcBoolean primaryAE = primaryFrame().approxEq(dh2.primaryFrame(), tol);
EcBoolean radiusAE =
fabs
(m_Radius - dh2.radius()) <
fabs
(tol);
return
parentAE && primaryAE;
}
void
CircleJoint::scaleBy
(
EcReal scaleFactor
)
{
m_Precursor.setTranslation(m_Precursor.translation()*scaleFactor);
m_Radius = m_Radius * scaleFactor;
}
void
CircleJoint::transformBy
(
const
EcCoordinateSystemTransformation& xform
)
{
m_Precursor = xform * m_Precursor;
}
EcReal CircleJoint::jointParameterScalability
(
)
const
{
return
1.0;
}
EcBoolean CircleJoint::read
(
EcXmlReader& stream
)
{
EcBoolean retVal = EcXmlCompoundType::read(stream);
m_PrimaryFrameInverse = m_PrimaryFrame.inverse();
return
retVal;
}
EcBoolean CircleJoint::write
(
EcXmlWriter& stream
)
const
{
EcBoolean retVal = EcXmlCompoundType::write(stream);
return
retVal;
}
CircleJoint CircleJoint::nullObject()
{
return
CircleJoint();
}
EcU32 CircleJoint::unitType()
const
{
return
LINEAR;
}
EcReal CircleJoint::upperBoundDhFrameDistance(
const
EcJointActuator& jointActuator)
const
{
EcReal retVal = 0;
retVal = EcMath::maximum(
calculateTransform
(jointActuator.upperLimit()).translation().mag(),
calculateTransform
(jointActuator.lowerLimit()).translation().mag());
return
retVal;
}
void
CircleJoint::changeInboardFrameBy
(
const
EcCoordinateSystemTransformation& offset
)
{
m_Precursor *= offset;
}
EcBoolean CircleJoint::selfTest()
const
{
CircleJoint rj1;
rj1.setRadius(200);
EcString filename = EcString(
"CircleJointSelfTest.xml"
);
EcXmlObjectReaderWriter::writeToFile(rj1, filename);
CircleJoint rj2;
EcXmlObjectReaderWriter::readFromFile(rj2, filename);
if
(!(rj1 == rj2))
{
EcPrint(Error) <<
"Circle Joint self test failed"
<< std::endl;
return
EcFalse;
}
return
EcTrue;
}