You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
5.2 KiB
127 lines
5.2 KiB
#ifndef _LSPBTRAJCETORY_H_
|
|
#define _LSPBTRAJCETORY_H_
|
|
#include <math.h>
|
|
#include "Trajectroy.h"
|
|
#include "sgn.h"
|
|
|
|
template <unsigned SIZE>
|
|
class LSPBJointTrajectory: public Trajectory<SIZE>
|
|
{
|
|
public:
|
|
LSPBJointTrajectory(
|
|
float sampleTimeMs,
|
|
Vec<float,SIZE> maxJointVelocity,
|
|
Vec<float,SIZE> maxJointAcceleration,
|
|
Vec<float,SIZE> jointStart,
|
|
Vec<float,SIZE> jointEnd
|
|
)
|
|
{
|
|
float MStoSec = 1000.0f;
|
|
// calculate maximum velocity and acceleration
|
|
Vec<float, SIZE> maxJointLocalVelocity = maxJointVelocity * (sampleTimeMs / MStoSec);
|
|
Vec<float, SIZE> maxJointLocalAcceleration = maxJointAcceleration * (sampleTimeMs / MStoSec);
|
|
std::cout << "max : " << maxJointLocalVelocity << "\n";
|
|
|
|
// calculate delta movement
|
|
Vec<float,SIZE> jointMovement = jointEnd - jointStart;
|
|
Vec<float,SIZE> jointMovementAbs = jointMovement.abs();
|
|
|
|
// calculate number of movement steps
|
|
|
|
// 2 same acceleration and deaceleration phases
|
|
|
|
Vec<float,SIZE> minStepsPerJoint(0.0f);
|
|
// check
|
|
for (int j=0; j<SIZE; j++)
|
|
{
|
|
// only need acceleration and deacceleration phase
|
|
if (maxJointLocalVelocity(j) > jointMovementAbs(j)/2.0f)
|
|
{
|
|
// s = (a * t^2 )/2
|
|
// => t = sqrt( s * 2 / a)
|
|
minStepsPerJoint(j) = sqrt(jointMovementAbs(j) / maxJointLocalAcceleration (j))*2.0f;
|
|
} else
|
|
{
|
|
// 2 speedup and slow down phases
|
|
minStepsPerJoint(j) = maxJointLocalVelocity(j)/maxJointLocalAcceleration(j) * 2.0f ;
|
|
|
|
// one phase with constant velocity
|
|
float remainingjointMovementAbs = jointMovementAbs(j);
|
|
// v * t = s
|
|
remainingjointMovementAbs -= maxJointLocalVelocity(j) * minStepsPerJoint(j) * sampleTimeMs;
|
|
|
|
// s / v = t
|
|
minStepsPerJoint(j) += remainingjointMovementAbs/maxJointLocalVelocity(j);
|
|
}
|
|
}
|
|
|
|
std::cout << "minsteps : " << minStepsPerJoint << "\n";
|
|
std::cout << "steps : " << minStepsPerJoint.max() << "\n";
|
|
this->steps = ceil(minStepsPerJoint.max());
|
|
std::cout << "steps : " << this->steps << "\n";
|
|
if (this->steps == 0)
|
|
this->steps +=1;
|
|
|
|
this->nodes = (struct Trajectory<SIZE>::trajectoryNode* ) calloc(sizeof(struct Trajectory<SIZE>::trajectoryNode),this->steps);
|
|
|
|
Vec<float,SIZE> jointLast = jointStart;
|
|
|
|
// calculate thime of max speed reaching
|
|
Vec<float,SIZE> deltaToMaxSpeed(0.0f);
|
|
Vec<float,SIZE> currJointLocalAcceleration(0.0f);
|
|
for (int j=0; j<SIZE; j++)
|
|
{
|
|
// ceil steps/2 - sqrt(steps^2 - jointmovementabs/maxaccelaration)
|
|
deltaToMaxSpeed(j) = ceil( this->steps /2.0f - sqrt((this->steps/2.0f)*(this->steps/2.0f) - jointMovementAbs(j)/maxJointAcceleration(j)));
|
|
if (deltaToMaxSpeed(j) <= 0.0f)
|
|
{
|
|
currJointLocalAcceleration(j) = 0.0f;
|
|
} else
|
|
{
|
|
currJointLocalAcceleration(j) = -jointMovementAbs(j)/(deltaToMaxSpeed(j)*deltaToMaxSpeed(j)-this->steps*deltaToMaxSpeed(j));
|
|
}
|
|
maxJointLocalVelocity(j) = deltaToMaxSpeed(j)*currJointLocalAcceleration(j);
|
|
}
|
|
|
|
Vec<float,SIZE> currentInk(0.0f);
|
|
Vec<float,SIZE> currentInkLast(0.0f);
|
|
Vec<float,SIZE> currentDist(0.0f);
|
|
Vec<float,SIZE> currentDistLast(0.0f);
|
|
|
|
for (int currStep=0; currStep<this->steps; currStep++)
|
|
{
|
|
for (int currJoint=0; currJoint<SIZE; currJoint++)
|
|
{
|
|
if (currStep+1 <= this->steps/2.0f)
|
|
{
|
|
currentInk(currJoint) = std::min(currentInkLast(currJoint)+maxJointLocalAcceleration(currJoint),maxJointLocalVelocity(currJoint));
|
|
}else if (currStep+1 > this->steps-deltaToMaxSpeed(currJoint))
|
|
{
|
|
currentInk(currJoint) = std::max(currentInkLast(currJoint)-maxJointLocalAcceleration(currJoint),0.0f);
|
|
}else
|
|
{
|
|
currentInk(currJoint) = currentInkLast(currJoint);
|
|
}
|
|
currentDist(currJoint) = currentDistLast(currJoint) + sgn(jointMovement(currJoint))*currentInk(currJoint);
|
|
this->nodes[currStep].jointPos(currJoint) += sgn(jointMovement(currJoint))*currentInk(currJoint);
|
|
this->nodes[currStep].velocity(currJoint) = currentInk(currJoint);
|
|
this->nodes[currStep].acceleration(currJoint) = currentInkLast(currJoint) - currentInk(currJoint);
|
|
|
|
currentDistLast(currJoint) = currentDist(currJoint);
|
|
currentInkLast(currJoint) = currentInk(currJoint);
|
|
}
|
|
}
|
|
|
|
// last step myth be to wide so cut it to the wanted position
|
|
this->nodes[this->steps-1].jointPos = jointEnd;
|
|
this->nodes[this->steps-1].velocity = maxJointLocalVelocity; // TODO this is not the truth
|
|
this->nodes[this->steps-1].acceleration = Vec<float,SIZE>(0.0f);
|
|
}
|
|
};
|
|
|
|
template <unsigned SIZE>
|
|
class LSPBCartTrajectory: public Trajectory<SIZE>
|
|
{
|
|
};
|
|
|
|
#endif
|