package org.reprap.machines; import org.reprap.utilities.Debug; /** * Small class to compute the optimum velocity profile given a starting and an ending * velocity, a maximum velocity that cannot be exceeded, and an acceleration. * * The result is either a single maximum velocity, v, inbetween the ends (in which case flat will be 1), or * an acceleration to maxSpeed at s1 from the start, movement at that velocity to s2, then deceleration to * the end (in which case flat will be 2). * * If flat is 0 on return, the starting and ending speeds are greater than the maximum allowed... * * @author Adrian * */ public class VelocityProfile { private double v, s1, s2; private int flat; public VelocityProfile(double s, double vStart, double maxSpeed, double vEnd, double acceleration) { if(maxSpeed <= vStart && maxSpeed <= vEnd) { flat = 0; return; } s1 = (2*acceleration*s - vStart*vStart + vEnd*vEnd)/(4*acceleration); v = Math.sqrt(2*acceleration*s1 + vStart*vStart); double f = s1/s; if(f < 0 || f > 1) { Debug.d("VelocityProfile - sm/s: " + f); s1 = Math.max(Math.min(s, s1), 0); } if(v <= maxSpeed) flat = 1; else { s2 = s - 0.5*(maxSpeed*maxSpeed - vEnd*vEnd)/acceleration; f = s2/s; if(f < 0 || f > 1) { Debug.d("VelocityProfile - s2/s: " + f); s2 = Math.max(Math.min(s, s2), 0); } s1 = 0.5*(maxSpeed*maxSpeed - vStart*vStart)/acceleration; f = s1/s; if(f < 0 || f > 1) { Debug.d("VelocityProfile - s1/s: " + f); s1 = Math.max(Math.min(s, s1), 0); } flat = 2; } } public double v() { return v; } public double s1() { return s1; } public double s2() { return s2; } public int flat() { return flat; } }