// ptp movement (sinus wave acceleration)
void writePositionDataPTPPrepareSinus(unsigned long ipoTime, unsigned long totalTime, unsigned long time, unsigned long max, unsigned long param, float* readBuffer, float* writeBuffer, float* tbs, float* tes, int* sgns, float* vmaxs, float* bmaxs)
{
int i;
float current, target;
float MAXS = max / 10.0;
float TIME = totalTime;
float BTIME = (float)time / 100.0;
float VMAX = (MAXS / ((1.0 - BTIME) * TIME)) ;
float BMAX = (2.0 * VMAX / (BTIME * TIME));
float vmax, bmax, se;
long int te, tb, tv, sgn;
int ipo = ipoTime;
// prepare write buffer -> unpack data from serial and store bytewise in buffer
for (i=0;i<AX12_COUNT;i++)
{
target = writeBuffer[i];
current = readBuffer[i];
vmax = VMAX;
bmax = BMAX;
se = (target - current);
if (se < 0)
{
sgn = -1;
se = -se;
}
else sgn = 1;
if (vmax*vmax > bmax * se)
{
vmax = sqrt(bmax * se);;
tb = ((long int)( 2.0 * vmax / (bmax * ipo))) * ipo;
tv = TIME - tb;
} else
{
tb = ((long int)( 2.0 * vmax / (bmax * ipo) + 0.5)) * ipo;
tv = TIME - tb;
}
if (tb == 0)
tb = 1;
if (tv == 0)
tv = 1;
te = tv + tb;
vmax = se / (float)tv;
bmax = 2.0 * vmax / (float)tb;
tes[i] = te;
sgns[i] = sgn;
tbs[i] = tb;
vmaxs[i] = vmax;
bmaxs[i] = bmax;
}
}
// ptp movement (sinus wave acceleration)
void writePositionDataPTPSinus(FILE* writeFile, unsigned long readPause, float* readBuffer,float* writeBuffer, float pos, float* tb, float* te, int* sgn, float* vmax, float* bmax)
{
int i;
long int current;
float se, t, tv;
// prepare write buffer -> unpack data from serial and store bytewise in buffer
for (i=0;i<AX12_COUNT;i++)
{
current = readBuffer[i];
t = pos * te[i];
tv = te[i] - tb[i];
if (t <= tb[i])
se = bmax[i] * (0.25 * t * t + (tb[i] * tb[i] / (8.0 * M_PI * M_PI)) * (cos(2.0*M_PI*t/tb[i])-1.0));
else if (t <= te[i] - tb[i])
se = vmax[i] * (t - 0.5 * tb[i]);
else
se = 0.5 * bmax[i] * (te[i] * (t + tb[i]) - 0.5*(t*t + te[i]*te[i] + 2.0 * tb[i]*tb[i]) + (tb[i]*tb[i]/(4.0 * M_PI * M_PI))*(1.0 - cos((2.0*M_PI/tb[i])*(t - tv))));
current += sgn[i] * (long int) (se);
if (current > 1023)
current = 1023;
else if (current < 0)
current = 0;
if (i==0)
{
char buffer[255];
sprintf(buffer, "%d\n", current);
fputs(buffer, writeFile);
}
}
}
// ptp movement (constant acceleration)
void writePositionDataPTPPrepare(unsigned long ipoTime, unsigned long totalTime, unsigned long time, unsigned long max, unsigned long param, float* readBuffer, float* writeBuffer, float* tbs, float* tes, int* sgns, float* vmaxs, float* bmaxs)
{
// conversion variables
int i;
float current, target;
float MAXS = max / 10.0;
float TIME = totalTime;
float BTIME = (float)time / 100.0;
float VMAX = (MAXS / ((1.0 - BTIME) * TIME)) ;
float BMAX = (VMAX / (BTIME * TIME));
printf("VMAX: %g BMAX: %g\n", VMAX, BMAX);
float vmax, bmax, se;
long int te, tb, tv, sgn;
int ipo = ipoTime;
// prepare write buffer -> unpack data from serial and store bytewise in buffer
for (i=0;i<AX12_COUNT;i++)
{
target = writeBuffer[i];
current = readBuffer[i];
vmax = VMAX;
bmax = BMAX;
se = (target - current);
if (se < 0)
{
sgn = -1;
se = -se;
}
else sgn = 1;
if (vmax*vmax > bmax * se)
{
if (i==0)
printf("too big\n");
vmax = sqrt(bmax * se);
tb = ((long int)( vmax / (bmax * ipo))) * ipo;
tv = TIME - tb;
} else
{
tb = ((long int)( vmax / (bmax * ipo) + 0.5)) * ipo;
tv = TIME - tb;
}
if (tb == 0)
tb = 1;
if (tv == 0)
tv = 1;
te = tv + tb;
vmax = se / (float)tv;
bmax = vmax / (float)tb;
tes[i] = te;
sgns[i] = sgn;
tbs[i] = tb;
vmaxs[i] = vmax;
bmaxs[i] = bmax;
}
switch (param)
{
case 1:
// synchronous ptp
// get max total time
long int temax = 0;
for (i=0; i<AX12_COUNT; i++)
if (tes[i] > temax)
temax = tes[i];
// recalculate max velocity and acceleration times
for (i=0; i<AX12_COUNT; i++)
{
target = writeBuffer[i];
current = readBuffer[i];
se = (target - current);
if (se < 0)
{
se = -se;
}
bmax = bmaxs[i];
vmax = bmax * temax;
vmax = 0.5 * vmax - sqrt(0.25*vmax*vmax - se * bmax);
tv = ((long int)( se / (vmax * ipo) + 0.5)) * ipo;
tb = temax - tv;
vmax = se / (float)tv;
bmax = vmax / (float)tb;
tes[i] = temax;
tbs[i] = tb;
vmaxs[i] = vmax;
bmaxs[i] = bmax;
}
break;
}
}
// ptp movement (constant acceleration)
void writePositionDataPTP(FILE* writeFile, unsigned long readPause, float* readBuffer,float* writeBuffer, float pos, float* tb, float* te, int* sgn, float* vmax, float* bmax)
{
int i;
long int current;
float se, t;
// prepare write buffer -> unpack data from serial and store bytewise in buffer
for (i=0;i<AX12_COUNT;i++)
{
current = readBuffer[i];
t = pos * te[i];
if (t <= tb[i])
se = 0.5 * bmax[i] * t * t;
else if (t <= te[i] - tb[i])
se = (vmax[i] * t - 0.5 * vmax[i] * vmax[i] / bmax[i]);
else
se = (vmax[i] * (te[i] - tb[i]) - 0.5 * bmax[i] * (te[i] - t) * (te[i] - t));
current += sgn[i] * (long int) (se);
if (current > 1023)
current = 1023;
else if (current < 0)
current = 0;
if (i==0)
{
char buffer[255];
sprintf(buffer, "%d\n", current);
fputs(buffer, writeFile);
}
}
}
void CTest::run(float* args, int argcount)
{
float current[AX12_COUNT];
float target[AX12_COUNT];
current[0] = 100;
target[0] = 400;
// important
unsigned long readPause = 2; //pause between keyframes in milliseconds
int totalipo = 20; // total number of keyframes
unsigned long time = 25; // acceleration end time 25% * totaltime
unsigned long max = 100; //
unsigned long param = 0;
float tbs[AX12_COUNT];
float tes[AX12_COUNT];
int sgns[AX12_COUNT];
float vmaxs[AX12_COUNT];
float bmaxs[AX12_COUNT];
writePositionDataPTPPrepare(readPause, totalipo * readPause, time, max, param, current, target, tbs, tes, sgns, vmaxs, bmaxs);
FILE *file;
file = fopen("data.txt", "w+");
float pos;
for (int i=0; i<=totalipo; i++)
writePositionDataPTP(file, readPause, current, target, (float)i/(float)totalipo, tbs, tes, sgns, vmaxs, bmaxs);
fclose(file);
}
if (t <= tb[i])
se = bmax[i] * (0.25 * t * t + (tb[i] * tb[i] / (8.0 * M_PI * M_PI)) * (cos(2.0*M_PI*t/tb[i])-1.0));
else if (t <= te[i] - tb[i])
se = vmax[i] * (t - 0.5 * tb[i]);
else
se = 0.5 * bmax[i] * (te[i] * (t + tb[i]) - 0.5*(t*t + te[i]*te[i] + 2.0 * tb[i]*tb[i]) + (tb[i]*tb[i]/(4.0 * M_PI * M_PI))*(1.0 - cos((2.0*M_PI/tb[i])*(t - tv))));
ipoData.interpolationPause = 20; // 2ms
while (isRunning)
{
if (getCurrentTime() >= robotData.readTime + ipoData.interpolationPause)
{
robotData.readTime = getCurrentTime();
doInterpolation();
}
}