|
|
@ -11,54 +11,83 @@ |
|
|
|
#include "Mat.h"
|
|
|
|
#include "Vec.h"
|
|
|
|
#include "Robot.h"
|
|
|
|
#include "lwr4.h"
|
|
|
|
|
|
|
|
bool SvrData::instanceFlag = false; |
|
|
|
SvrData* SvrData::single = 0; |
|
|
|
|
|
|
|
/**
|
|
|
|
* private Default Constructor which is initializing everything to the default parameters. |
|
|
|
* |
|
|
|
* By default 10% of the Maximum Velocity and Acceleration is used. |
|
|
|
* Also the default robot is the LWR4 and a sample time of 5 ms |
|
|
|
* |
|
|
|
* This is a private constructor so only getInstance can call this |
|
|
|
* Constructor once and keep this class a singleton. |
|
|
|
* |
|
|
|
* @see getInstance |
|
|
|
*/ |
|
|
|
SvrData::SvrData(void) |
|
|
|
{ |
|
|
|
// these are the default values for the robot
|
|
|
|
double maxVelJnt[] = {110.0,110.0,128.0,128.0,204.0,184.0,184.0}; |
|
|
|
double maxAccJnt[] = {1.0,1.0,1.0,1.0,2.0,1.0,1.0}; |
|
|
|
double maxTrqJnt[] = {176.0,176.0,100.0,100.0,100.0,38.0,38.0}; |
|
|
|
double maxRangeJnt[] = {170.0,120.0,170.0,120.0,170.0,120.0,170.0}; |
|
|
|
|
|
|
|
// only use 10 percent of the maximum velocity by default
|
|
|
|
robot.currentVelocityPercentage = 10; |
|
|
|
robot.currentAccelerationPercentage = 10; |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < Robot::joints; ++i) |
|
|
|
{ |
|
|
|
robot.max.velocity(i) = maxVelJnt[i]; |
|
|
|
robot.max.accelaration(i) = maxAccJnt[i]; |
|
|
|
robot.max.torque(i) = maxTrqJnt[i]; |
|
|
|
robot.max.range(i) = maxRangeJnt[i]; |
|
|
|
} |
|
|
|
// use the lwr4 robot by default
|
|
|
|
robot.robotClass = new LWR4(); |
|
|
|
|
|
|
|
// use 5ms interval for each step
|
|
|
|
trajectory.sampleTimeMs = 5.0f; |
|
|
|
|
|
|
|
// do not cancel current trajectory (there also should not be any at this point)
|
|
|
|
trajectory.cancel = false; |
|
|
|
|
|
|
|
// init mutex for database
|
|
|
|
if (pthread_mutex_init(&dataLock, NULL) != 0) |
|
|
|
printf("mutex init failed\n"); |
|
|
|
printf("mutex initializing failed\n"); |
|
|
|
|
|
|
|
// connect to the fri remote interface
|
|
|
|
this->friInst = new friRemote(); |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor for cleaning up the memory |
|
|
|
*/ |
|
|
|
SvrData::~SvrData() |
|
|
|
{ |
|
|
|
pthread_mutex_destroy(&dataLock); |
|
|
|
delete robot.robotClass; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns always the same reference to the SvrData. |
|
|
|
* For the first call it will call the private Constructor otherwise |
|
|
|
* it will return the same reference like the first time. |
|
|
|
* |
|
|
|
* @return A pointer to the SvrData singleton class |
|
|
|
*/ |
|
|
|
|
|
|
|
SvrData* SvrData::getInstance () |
|
|
|
{ |
|
|
|
// check if the instance was already initialized
|
|
|
|
if (instanceFlag) |
|
|
|
return single; |
|
|
|
|
|
|
|
// first time so we have to create a new instance of SvrData
|
|
|
|
single = new SvrData(); |
|
|
|
|
|
|
|
// mark the success on initializing to not allocate a second
|
|
|
|
// SvrData reference
|
|
|
|
instanceFlag = true; |
|
|
|
|
|
|
|
return single; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the same reference to the FRI remote interface |
|
|
|
* |
|
|
|
* @return a pointer to the FRI class |
|
|
|
*/ |
|
|
|
friRemote* SvrData::getFriRemote() |
|
|
|
{ |
|
|
|
friRemote* retval = NULL; |
|
|
@ -66,35 +95,54 @@ friRemote* SvrData::getFriRemote() |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = this->friInst; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
void SvrData::updateMessurementData( |
|
|
|
/**
|
|
|
|
* This function updates the measured Units directly |
|
|
|
* via function parameters |
|
|
|
* |
|
|
|
* @param newJointPos new measured Unit for the joint angles |
|
|
|
* @param newCartPos new measured homogeneous cartesian positions |
|
|
|
* @param newForceAndTorque new measured force and torque for the end effector |
|
|
|
* |
|
|
|
* @see updateMeasurement |
|
|
|
*/ |
|
|
|
void SvrData::updateMeasurementData( |
|
|
|
Robot::VecJoint newJointPos, |
|
|
|
MatCarthesian newCartPos, |
|
|
|
VecTorque newForceAndTorque |
|
|
|
) |
|
|
|
{ |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
|
|
|
|
this->messured.jointPos = newJointPos; |
|
|
|
this->messured.cartPos = newCartPos; |
|
|
|
this->messured.forceAndTorque = newForceAndTorque; |
|
|
|
|
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
} |
|
|
|
|
|
|
|
void SvrData::updateMessurement() |
|
|
|
/**
|
|
|
|
* This function updates the measured Units directly |
|
|
|
* via the FRI remote instance and saves them into the database. |
|
|
|
* |
|
|
|
* @see updateMeasurementData |
|
|
|
*/ |
|
|
|
void SvrData::updateMeasurement() |
|
|
|
{ |
|
|
|
Robot::VecJoint newJointPos(0.0f); |
|
|
|
MatCarthesian newCartPos(0.0f,1.0f); |
|
|
|
VecTorque newForceAndTorque(0.0f); |
|
|
|
|
|
|
|
/// do the update using fri
|
|
|
|
/// do the update using the FRI Interface
|
|
|
|
/// update current joint positions
|
|
|
|
friInst->getState(); |
|
|
|
FRI_STATE state = friInst->getState(); |
|
|
|
Robot::VecJoint newJointPosComanded(friInst->getMsrCmdJntPosition()); |
|
|
|
Robot::VecJoint newJointPosOffset(friInst->getMsrCmdJntPositionOffset()); |
|
|
|
newJointPos = newJointPosComanded + newJointPosOffset; |
|
|
|
|
|
|
|
// convert the joints from radian to degree
|
|
|
|
newJointPos = newJointPos * ( 180.0f / M_PI); |
|
|
|
|
|
|
|
/// update current cart position
|
|
|
@ -102,48 +150,87 @@ void SvrData::updateMessurement() |
|
|
|
|
|
|
|
/// update current force and torque
|
|
|
|
newForceAndTorque = friInst->getFTTcp(); |
|
|
|
std::cout << newJointPos << " current newJointPos \n" << state << "\n"; |
|
|
|
|
|
|
|
updateMessurementData(newJointPos,newCartPos,newForceAndTorque); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SvrData::lock() |
|
|
|
{ |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
/// save the new values to the database
|
|
|
|
updateMeasurementData(newJointPos,newCartPos,newForceAndTorque); |
|
|
|
} |
|
|
|
|
|
|
|
void SvrData::unlock() |
|
|
|
{ |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
} |
|
|
|
|
|
|
|
Robot::VecJoint SvrData::getMessuredJointPos() |
|
|
|
/**
|
|
|
|
* This function returns the current measurement of the joints |
|
|
|
* within the database. |
|
|
|
* This value will be updated if updateMeasurement was called |
|
|
|
* which is done by the robot server thread. |
|
|
|
* |
|
|
|
* @see updateMeasurement |
|
|
|
* @see threadRobotMovement |
|
|
|
*/ |
|
|
|
Robot::VecJoint SvrData::getMeasuredJointPos() |
|
|
|
{ |
|
|
|
Robot::VecJoint buf; |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
buf = messured.jointPos; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return buf; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current measurement homogeneous |
|
|
|
* cartesian positions within the database. |
|
|
|
* |
|
|
|
* This value will be updated if updateMeasurement was called |
|
|
|
* which is done by the robot server thread. |
|
|
|
* |
|
|
|
* @see updateMeasurement |
|
|
|
* @see threadRobotMovement |
|
|
|
*/ |
|
|
|
MatCarthesian SvrData::getMessuredCartPos() |
|
|
|
{ |
|
|
|
MatCarthesian buf; |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
buf = messured.cartPos; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return buf; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current measurement force and |
|
|
|
* torque within the database. |
|
|
|
* |
|
|
|
* This value will be updated if updateMeasurement was called |
|
|
|
* which is done by the robot server thread. |
|
|
|
* |
|
|
|
* @see updateMeasurement |
|
|
|
* @see threadRobotMovement |
|
|
|
*/ |
|
|
|
VecTorque SvrData::getMessuredForceTorque() |
|
|
|
{ |
|
|
|
VecTorque buf; |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
buf = messured.forceAndTorque; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return buf; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current Jacobian matrix. |
|
|
|
* |
|
|
|
* This value will be updated if updateMeasurement was called |
|
|
|
* which is done by the robot server thread. |
|
|
|
* |
|
|
|
* @param data pointer for the matrix for the jacobian matrix |
|
|
|
* @param size the size of the given data pointer to prevent segmentation faults |
|
|
|
* |
|
|
|
* @return 0 on success and the negative error code if an error occurred. |
|
|
|
* |
|
|
|
* @see updateMeasurement |
|
|
|
* @see threadRobotMovement |
|
|
|
*/ |
|
|
|
int SvrData::getMessuredJacobian(float* data, size_t size) |
|
|
|
{ |
|
|
|
if (data == NULL) |
|
|
@ -154,31 +241,67 @@ int SvrData::getMessuredJacobian(float* data, size_t size) |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
memcpy(data,messured.jacobian,size); |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current commanded joint positions |
|
|
|
* |
|
|
|
* @return Vector for the current commanded joint values in unit [degree] |
|
|
|
* |
|
|
|
* @see setCommandedJointPos |
|
|
|
*/ |
|
|
|
Robot::VecJoint SvrData::getCommandedJointPos() |
|
|
|
{ |
|
|
|
Robot::VecJoint buff; |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
buff = commanded.jointPos; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return buff; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current commanded |
|
|
|
* |
|
|
|
* @return Vector for the current commanded joint values in unit [degree] |
|
|
|
* |
|
|
|
* @see getCommandedJointPos |
|
|
|
*/ |
|
|
|
void SvrData::setCommandedJointPos(Robot::VecJoint newJointPos) |
|
|
|
{ |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
commanded.jointPos = newJointPos; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current commanded position |
|
|
|
* |
|
|
|
* @return Matrix for the current commanded cartesian homogeneous values |
|
|
|
* |
|
|
|
* @see setCommandedCartPos |
|
|
|
*/ |
|
|
|
MatCarthesian SvrData::getCommandedCartPos () |
|
|
|
{ |
|
|
|
MatCarthesian buff; |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
buff = commanded.cartPos; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return buff; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function sets the current commanded position |
|
|
|
* |
|
|
|
* @return Matrix for the current commanded cartesian homogeneous values |
|
|
|
* |
|
|
|
* @see getCommandedCartPos |
|
|
|
*/ |
|
|
|
void SvrData::setCommandedCartPos(MatCarthesian newCartPos) |
|
|
|
{ |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
@ -187,40 +310,96 @@ void SvrData::setCommandedCartPos(MatCarthesian newCartPos) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current maximum force and torque per joint |
|
|
|
* for the configured Robot. |
|
|
|
* |
|
|
|
* @return Vector containing the Torque in the unit [ Nm ] |
|
|
|
*/ |
|
|
|
Robot::VecJoint SvrData::getMaxTorque() |
|
|
|
{ |
|
|
|
Robot::VecJoint buff; |
|
|
|
Robot::VecJoint retval; |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
buff = robot.max.torque; |
|
|
|
retval = robot.robotClass->getJointCount(); |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
return buff; |
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current maximum acceleration per joint |
|
|
|
* for the configured Robot. |
|
|
|
* |
|
|
|
* @return Vector containing the maximum acceleration [ degree/ seconds^2 ] |
|
|
|
*/ |
|
|
|
Robot::VecJoint SvrData::getMaxAcceleration() |
|
|
|
{ |
|
|
|
Robot::VecJoint retval(0.0f); |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = robot.max.accelaration; |
|
|
|
retval = robot.robotClass->getJointAcceleration(); |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current maximum velocity per joint |
|
|
|
* for the configured Robot. |
|
|
|
* |
|
|
|
* @return Vector containing the maximum velocity [ degree/ seconds ] |
|
|
|
*/ |
|
|
|
Robot::VecJoint SvrData::getMaxVelocity() |
|
|
|
{ |
|
|
|
Robot::VecJoint retval(0.0f); |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = robot.max.velocity; |
|
|
|
retval = robot.robotClass->getJointVelocity(); |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current maximum range per joint |
|
|
|
* for the configured Robot. |
|
|
|
* |
|
|
|
* @return Vector containing the maximum angle for the joints [ degree ] |
|
|
|
*/ |
|
|
|
Robot::VecJoint SvrData::getMaxRange() |
|
|
|
{ |
|
|
|
Robot::VecJoint retval(0.0f); |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = robot.max.range; |
|
|
|
retval = robot.robotClass->getJointRangeMax(); |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current minimum range per joint |
|
|
|
* for the configured Robot. |
|
|
|
* |
|
|
|
* @return Vector containing the minimum angle for the joints [ degree ] |
|
|
|
*/ |
|
|
|
Robot::VecJoint SvrData::getMinRange() |
|
|
|
{ |
|
|
|
Robot::VecJoint retval(0.0f); |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = robot.robotClass->getJointRangeMin(); |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* This function returns the current minimum range per joint |
|
|
|
* for the configured Robot. |
|
|
|
* |
|
|
|
* @return Vector containing the minimum angle for the joints [ degree ] |
|
|
|
*/ |
|
|
|
bool SvrData::checkJointRange(Robot::VecJoint vectorToCheck) |
|
|
|
{ |
|
|
|
// save temporal the max range for short time lock
|
|
|
@ -230,7 +409,7 @@ bool SvrData::checkJointRange(Robot::VecJoint vectorToCheck) |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
// check if the value is in plus or minus range
|
|
|
|
for (int i = 0; i<Robot::joints; i++) |
|
|
|
for (int i = 0; i< robot.robotClass->joints; i++) |
|
|
|
{ |
|
|
|
if (abs(vectorToCheck(i)) > abs(maxJointRange(i))) |
|
|
|
{ |
|
|
@ -264,7 +443,7 @@ Robot::VecJoint SvrData::getRobotVelocity() |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
percent = robot.currentVelocityPercentage / 100.0f; |
|
|
|
retval = robot.max.velocity * percent; |
|
|
|
retval = robot.robotClass->getJointVelocity() * percent; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
return retval; |
|
|
|
} |
|
|
@ -275,6 +454,7 @@ float SvrData::getRobotVelocityPercentage() |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = robot.currentVelocityPercentage; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
int SvrData::setRobotAccelerationPercentage(float newAccelerationPercentage) |
|
|
@ -290,6 +470,7 @@ int SvrData::setRobotAccelerationPercentage(float newAccelerationPercentage) |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
robot.currentAccelerationPercentage = newAccelerationPercentage; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
Robot::VecJoint SvrData::getRobotAcceleration() |
|
|
@ -299,8 +480,9 @@ Robot::VecJoint SvrData::getRobotAcceleration() |
|
|
|
|
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
percent = robot.currentAccelerationPercentage / 100.0f; |
|
|
|
retval = robot.max.accelaration * percent; |
|
|
|
retval = robot.robotClass->getJointAcceleration() * percent; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
float SvrData::getRobotAccelerationPercentage() |
|
|
@ -310,6 +492,7 @@ float SvrData::getRobotAccelerationPercentage() |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = robot.currentAccelerationPercentage; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
unsigned int SvrData::getJoints() |
|
|
@ -319,6 +502,7 @@ unsigned int SvrData::getJoints() |
|
|
|
pthread_mutex_lock(&dataLock); |
|
|
|
retval = Robot::joints; |
|
|
|
pthread_mutex_unlock(&dataLock); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|