42                                           float directSetVLimit)
 
   46         acceleration = 
std::abs(acceleration);
 
   47         deceleration = 
std::abs(deceleration);
 
   56         const float curverror = targetV - currentV;
 
   57         if (
std::abs(curverror) < directSetVLimit)
 
   63         const bool accelerate = 
sign(targetV) == 
sign(currentV) && 
 
   66         const float usedacc = accelerate ? acceleration : -deceleration;
 
   67         const float maxDeltaV = 
std::abs(usedacc * 
dt);
 
   68         if (maxDeltaV >= 
std::abs(curverror))
 
   75         const float deltaVel = 
std::clamp(
sign(currentV) * usedacc * 
dt, -maxDeltaV, maxDeltaV);
 
   76         const float nextV = currentV + deltaVel;
 
   90                                                      float directSetVLimit,
 
   91                                                      float currentPosition,
 
   92                                                      float positionLimitLoSoft,
 
   93                                                      float positionLimitHiSoft,
 
   94                                                      float positionLimitLoHard,
 
   95                                                      float positionLimitHiHard)
 
   97         if (currentPosition <= positionLimitLoHard || currentPosition >= positionLimitHiHard)
 
   99             return std::nanf(
"1");
 
  102         float softLimitViolation = 0;
 
  103         if (currentPosition <= positionLimitLoSoft)
 
  105             softLimitViolation = -1;
 
  107         if (currentPosition >= positionLimitHiSoft)
 
  109             softLimitViolation = 1;
 
  123         const float vsquared = currentV * currentV;
 
  124         const float brakingDist =
 
  125             sign(currentV) * vsquared / 2.f /
 
  129         const float posIfBrakingNow = currentPosition + brakingDist;
 
  130         if (posIfBrakingNow <= positionLimitLoSoft || posIfBrakingNow >= positionLimitHiSoft)
 
  134                 posIfBrakingNow <= positionLimitLoSoft ? positionLimitLoSoft : positionLimitHiSoft;
 
  135             const float wayToGo = limit - currentPosition;
 
  139             const float dec = 
std::abs(vsquared / 2.f / wayToGo);
 
  140             const float vel = currentV - 
sign(currentV) * dec * upperDt;
 
  152                 dt, maxDt, currentV, targetV, maxV, acceleration, deceleration, directSetVLimit);
 
  154         if (softLimitViolation == 
sign(nextv))
 
  172                                                          float currentPosition,
 
  173                                                          float targetPosition,
 
  178         acceleration = 
std::abs(acceleration);
 
  179         deceleration = 
std::abs(deceleration);
 
  180         const float signV = 
sign(currentV);
 
  189         const float positionError = targetPosition - currentPosition;
 
  190         float newTargetVelPController = positionError * p;
 
  194             signV * currentV * currentV / 2.f /
 
  197         const float posErrorIfBrakingNow = targetPosition - posIfBrakingNow;
 
  199         const bool decelerate =
 
  202             sign(posErrorIfBrakingNow) != signV; 
 
  203         const float usedacc = decelerate ? -deceleration : acceleration;
 
  204         const float maxDeltaV = 
std::abs(usedacc * 
dt);
 
  205         const float deltaVel = 
std::clamp(signV * usedacc * 
dt, -maxDeltaV, maxDeltaV);
 
  207         float newTargetVel = 
std::clamp(currentV + deltaVel, -maxV, maxV);
 
  213             return newTargetVelPController;
 
  228                                                                     float currentPosition,
 
  229                                                                     float targetPosition,
 
  231                                                                     float positionLimitLo,
 
  232                                                                     float positionLimitHi
 
  238         acceleration = 
std::abs(acceleration);
 
  239         deceleration = 
std::abs(deceleration);
 
  240         const float signV = 
sign(currentV);
 
  250         const float vsquared = currentV * currentV;
 
  252             signV * vsquared / 2.f /
 
  255         if (posIfBrakingNow <= positionLimitLo || posIfBrakingNow >= positionLimitHi)
 
  258             const auto limit = 
brakingDistance > 0 ? positionLimitHi : positionLimitLo;
 
  259             const float wayToGo = 
std::abs(limit - currentPosition);
 
  261             const float dec = 
std::abs(vsquared / 2.f / wayToGo);
 
  262             const float vel = currentV - signV * dec * 
dt;
 
  275             std::clamp(targetPosition, positionLimitLo, positionLimitHi),
 
  291         float currentPosition,
 
  292         float targetPosition,
 
  293         float pControlPosErrorLimit,
 
  296         float positionPeriodLo,
 
  297         float positionPeriodHi)
 
  299         currentPosition = 
periodicClamp(currentPosition, positionPeriodLo, positionPeriodHi);
 
  300         targetPosition = 
periodicClamp(targetPosition, positionPeriodLo, positionPeriodHi);
 
  303         const float posIfBrakingNow = currentPosition + brakingDist;
 
  304         const float posIfBrakingNowError = targetPosition - posIfBrakingNow;
 
  305         const float posError = targetPosition - currentPosition;
 
  306         if (
std::abs(posIfBrakingNowError) <= pControlPosErrorLimit ||
 
  307             std::abs(posError) <= pControlPosErrorLimit)
 
  323         const float positionPeriodLength = 
std::abs(positionPeriodHi - positionPeriodLo);
 
  327             periodicClamp(currentPosition - targetPosition, 0.f, positionPeriodLength);
 
  329         const float overshoot = std::trunc((currentPosition + brakingDist) / positionPeriodLength);
 
  331         if (
true || direction == 0)
 
  334             direction = (
periodicClamp(currentPosition + brakingDist, 0.f, positionPeriodLength) >=
 
  335                          positionPeriodLength / 2)
 
  340         targetPosition = (overshoot - 
std::min(0.f, -direction)) *
 
  341                          positionPeriodLength; 
 
  383         const float maxDeltaV = 
std::abs(usedacc * useddt);
 
  384         if (maxDeltaV >= 
std::abs(curverror))
 
  392         const float nextV = 
currentV + deltaVel;
 
  399         return maxV > 0 && 
jerk > 0 && targetV <= maxV && targetV >= -
maxV;
 
  413         const double curverror = clampedTargetV - 
currentV;
 
  418             Output result{clampedTargetV, 0, 0};
 
  428         bool increaseAcc = 
true;
 
  441         const double adjustedJerk =
 
  443         double usedJerk = increaseAcc
 
  455         if (maxDeltaV >= 
std::abs(curverror))
 
  459             double nextAcc = (clampedTargetV - 
currentV) / useddt;
 
  460             double nextJerk = (nextAcc - 
currentAcc) / useddt;
 
  462             Output result{clampedTargetV, nextAcc, nextJerk};
 
  469         Output result{nextV, nextAcc, usedJerk};
 
  502         float softLimitViolation = 0;
 
  505             softLimitViolation = -1;
 
  509             softLimitViolation = 1;
 
  522         const float brakingDist =
 
  538             const float dec = 
std::abs(vsquared / 2.f / wayToGo);
 
  554         if (softLimitViolation == 
sign(nextv) && nextv != 0)
 
  569 #ifdef DEBUG_POS_CTRL 
  570         buffer = boost::circular_buffer<HelpStruct>(20);
 
  573         pid->threadSafe = 
false;
 
  611         float newTargetVelPController = 
pid->getControlValue();
 
  618         const float posErrorIfBrakingNow = 
targetPosition - posIfBrakingNow;
 
  620         const float safePositionError =
 
  621             (
std::abs(positionError) < 0.0001) ? (
sign(positionError) * 0.0001) : positionError;
 
  622         const float usedDeceleration = hardBrakingNeeded
 
  626         const bool decelerate =
 
  629             sign(posErrorIfBrakingNow) != signV; 
 
  631         const float usedacc = decelerate ? -usedDeceleration : 
acceleration;
 
  632         const float deltaVel = signV * usedacc * useddt;
 
  641         this->currentlyPIDActive = PIDActive;
 
  642         float finalTargetVel =
 
  643             (currentlyPIDActive) ? newTargetVelPController : newTargetVelRampCtrl;
 
  657 #ifdef DEBUG_POS_CTRL 
  659                           newTargetVelPController,
 
  660                           newTargetVelRampCtrl,
 
  663                           IceUtil::Time::now().toMicroSeconds()});
 
  666         if (buffer.size() > 0 &&
 
  667             sign(positionError) * 
sign(buffer[buffer.size() - 2].currentError) < 0 &&
 
  668             eventHappeningCounter < 0)
 
  670             eventHappeningCounter = 10;
 
  673         if (eventHappeningCounter == 0)
 
  676             for (
auto& elem : buffer)
 
  679                             << 
VAROUT(elem.targetVelocityRAMP) << 
VAROUT(elem.currentV)
 
  685         if (eventHappeningCounter >= 0)
 
  687             eventHappeningCounter--;
 
  694         PIDModeActive = usePID;
 
  697         return finalTargetVel;
 
  711         const float posErrorIfBrakingNow = 
targetPosition - posIfBrakingNow;
 
  720         if (
sign(posError) != 
sign(posErrorIfBrakingNow))
 
  724             curPos = posIfBrakingNow;
 
  745         return t + tr.at(0).dt + tr.at(1).dt + tr.at(2).dt;
 
  772             signV * vsquared / 2.f /
 
  784             const float dec = 
std::abs(vsquared / 2.f / wayToGo);
 
  785             const float vel = 
currentV - signV * dec * useddt;
 
  794     std::array<deltas, 3>
 
  795     trapeze(
float v0, 
float acc, 
float vMax, 
float dec, 
float vt, 
float dx)
 
  800         auto calc = [&](
float vmax)
 
  804             const float dxMax = dacc.
dx + ddec.
dx;
 
  813                     return std::make_pair(
true, std::array<deltas, 3>{dacc, mid, ddec});
 
  829                 const float a0 = acc;
 
  830                 const float at = dec;
 
  831                 const float div = (1.f / 2.f / a0 + 1.f / 2.f / at);
 
  832                 const float p = (v0 / 2.f - v0 / a0 + vt / 2.f - vt / at) / div;
 
  834                     (v0 * v0 / 2.f * (1.f / a0 - 1.f) + vt * vt / 2.f * (1.f / at - 1.f) - dx) /
 
  836                 const auto vxs = 
pq(p, 
q);
 
  840                 switch (vx1Valid + vx2Valid)
 
  843                         return std::make_pair(
false, std::array<deltas, 3>());
 
  846                         float vx = vx1Valid ? vxs.first : vxs.second;
 
  853                         return std::make_pair(
true, std::array<deltas, 3>{daccvx, mid, ddecvx});
 
  864                         if (daccvx1.
dt + ddecvx1.
dt < daccvx2.
dt + ddecvx2.
dt)
 
  867                             return std::make_pair(
true,
 
  868                                                   std::array<deltas, 3>{daccvx1, mid, ddecvx1});
 
  871                         return std::make_pair(
true, std::array<deltas, 3>{daccvx2, mid, ddecvx2});
 
  874                         throw std::logic_error{
"unreachable code (bool + bool neither 0,1,2)"};
 
  877             return std::make_pair(
false, std::array<deltas, 3>());
 
  880         const auto plusVMax = calc(vMax);
 
  881         const auto negVMax = calc(-vMax);
 
  882         switch (plusVMax.first + negVMax.first)
 
  885                 throw std::invalid_argument(
"could not find a trapez to reach the goal");
 
  887                 return plusVMax.first ? plusVMax.second : negVMax.second;
 
  891                     plusVMax.second.at(0).dt + plusVMax.second.at(1).dt + plusVMax.second.at(2).dt;
 
  893                     negVMax.second.at(0).dt + negVMax.second.at(1).dt + negVMax.second.at(2).dt;
 
  894                 return dt1 < dt2 ? plusVMax.second : negVMax.second;
 
  897                 throw std::logic_error{
"unreachable code (bool + bool neither 0,1,2)"};
 
  930                                             -positionPeriodLength * 0.5f,
 
  931                                             positionPeriodLength * 0.5f);
 
  933         const float overshoot = std::trunc((
currentPosition + brakingDist) / positionPeriodLength);
 
  941                                        -positionPeriodLength * 0.5f,
 
  942                                        positionPeriodLength * 0.5f) <= 0)
 
  948             (overshoot * -direction) * positionPeriodLength; 
 
  963         return currentlyPIDActive;
 
 1005         double newTargetVelPController = (positionError * 
p) * 0.5 + 
currentV * 0.5;
 
 1018         std::tie(newState, output) = 
calcState();
 
 1019         usedAbsJerk = output.
jerk;
 
 1030         const double posErrorIfBrakingNow = 
targetPosition - posIfBrakingNow;
 
 1034         const double jerkDir =
 
 1036         const double usedJerk = goalDir * jerkDir * usedAbsJerk;
 
 1037         const double deltaAcc = usedJerk * useddt;
 
 1038         const double newAcceleration =
 
 1043         result.
jerk = usedJerk;
 
 1045         const double usedDeceleration =
 
 1049         (void)usedDeceleration;
 
 1051         const bool decelerate =
 
 1053             hardBrakingNeeded ||
 
 1054             sign(posErrorIfBrakingNow) != signV; 
 
 1057         const double deltaVel =
 
 1058             ctrlutil::v(useddt, 0, newAcceleration, usedJerk); 
 
 1061         double newTargetVelRampCtrl =
 
 1067         bool usePID = 
std::abs(newTargetVelPController) < 
std::abs(newTargetVelRampCtrl); 
 
 1076         double finalTargetVel = usePID ? newTargetVelPController : newTargetVelRampCtrl;
 
 1086 #ifdef DEBUG_POS_CTRL 
 1088                           newTargetVelPController,
 
 1089                           newTargetVelRampCtrl,
 
 1092                           IceUtil::Time::now().toMicroSeconds()});
 
 1095         if (buffer.size() > 0 &&
 
 1096             sign(positionError) * 
sign(buffer[buffer.size() - 2].currentError) < 0 &&
 
 1097             eventHappeningCounter < 0)
 
 1099             eventHappeningCounter = 10;
 
 1102         if (eventHappeningCounter == 0)
 
 1105             for (
auto& elem : buffer)
 
 1108                             << 
VAROUT(elem.targetVelocityRAMP) << 
VAROUT(elem.currentV)
 
 1109                             << 
VAROUT(elem.currentError) << 
VAROUT(elem.timestamp);
 
 1114         if (eventHappeningCounter >= 0)
 
 1116             eventHappeningCounter--;
 
 1123         PIDModeActive = usePID;
 
 1132         throw LocalException(
"NYI");
 
 1163         const auto straightBrakingDistance =
 
 1165         const double brakingDistance = brData.dt2 < 0 ? straightBrakingDistance : brData.s_total;
 
 1167         const double t_to_stop =
 
 1169         const auto calculatedJerk =
 
 1171         double tmp_t, tmp_acc, tmp_jerk;
 
 1173         std::tie(tmp_t, tmp_acc, tmp_jerk) =
 
 1175         const double posWhenBrakingWithCustomJerk =
 
 1178         const double posWhenBrakingWithFixedJerk = 
ctrlutil::s(
 
 1180         (void)calculatedJerk, (
void)posWhenBrakingWithCustomJerk, (void)posWhenBrakingWithFixedJerk;
 
 1202              || curVDir != goalDir)) 
 
 1208                 return std::make_pair(newState, result);
 
 1217                 return std::make_pair(newState, result);
 
 1222                 return std::make_pair(newState, result);
 
 1232             const double posWhenBrakingNow =
 
 1234             const double simpleBrakingDistance =
 
 1236             (void)tmpV, (
void)vAfterBraking, (void)accAfterBraking, (
void)posWhenBrakingNow,
 
 1237                 (void)simpleBrakingDistance;
 
 1240             std::tie(t, a0, newJerk) =
 
 1245             (void)at, (
void)vt, (void)st;
 
 1250                 return std::make_pair(newState, result);
 
 1255                 result.
jerk = newJerk;
 
 1258                 return std::make_pair(newState, result);
 
 1262                 return std::make_pair(newState, result);
 
 1265         throw LocalException();
 
 1443         double softLimitViolation = 0;
 
 1446             softLimitViolation = -1;
 
 1450             softLimitViolation = 1;
 
 1463         const double brakingDist =
 
 1479             const double dec = 
std::abs(vsquared / 2.0 / wayToGo);
 
 1481             nextv = std::clamp<double>(vel, -
maxV, 
maxV);
 
 1495         if (softLimitViolation == 
sign(nextv) && nextv != 0)
 
 1505         return Output{nextv, 0, 0};
 
 1515             double rawFinishTime = 0.0;
 
 1525                 rawFinishTime = decelerationTime;
 
 1530                 double accelerationTime = 
std::abs(
 
 1533                 rawFinishTime = 
std::max(decelerationTime + accelerationTime,
 
 1538             double minTime = 0.8;
 
 1539             if (!std::isnan(estimatedTime))
 
 1555         auto min_jerk_calc_jerk =
 
 1556             [&](
double tf, 
double s0, 
double v0, 
double a0, 
double xf = 0, 
double t0 = 0.0)
 
 1559             return 60.0 / (D * D * D) * (xf - s0) - 36.0 / (D * D) * v0 - 9.0 / D * a0;
 
 1563         auto min_jerk = [&](
double t,
 
 1574             double tau = (t - t0) / D;
 
 1577             double b2 = D2 * a0 / 2;
 
 1579             double b3 = (-3 * D2) / 2 * a0 - 6 * D * v0 + 10 * (xf - s0);
 
 1580             double b4 = (3 * D2) / 2 * a0 + 8 * D * v0 - 15 * (xf - s0);
 
 1581             double b5 = (-D2) / 2 * a0 - 3 * D * v0 + 6 * (xf - s0);
 
 1583             double tau2 = tau * tau;
 
 1584             double tau3 = tau2 * tau;
 
 1585             double tau4 = tau3 * tau;
 
 1586             double tau5 = tau4 * tau;
 
 1587             double st = b0 + b1 * tau + b2 * tau2 + b3 * tau3 + b4 * tau4 + b5 * tau5;
 
 1588             double vt = b1 / D + 2 * b2 / D * tau + 3 * b3 / D * tau2 + 4 * b4 / D * tau3 +
 
 1590             double at = 2 * b2 / D2 + 6 * b3 / D2 * tau + 12 * b4 / D2 * tau2 + 20 * b5 / D2 * tau3;
 
 1591             return State{t, st, vt, at};
 
 1596         if (remainingTime <= 0.0)
 
 1606                 if (signedDistance == 0.0f)
 
 1625             Output result{newPos, newVel, newAcc, newJerk};
 
 1658             double newAcc = (newVelocity - 
currentV) / 
dt;
 
 1667             Output result{newPos, newVelocity, newAcc, newJerk};
 
 1672         double jerk = min_jerk_calc_jerk(
 
 1682         std::vector<State> states;
 
 1683         std::vector<State> states2;
 
 1693                 simAcc = simAcc + 
jerk * 
dt;
 
 1697                 states.push_back(
State{t, simS, simV, simAcc, 
jerk});
 
 1710                 simAcc = simAcc + 
jerk * 
dt;
 
 1712                 states2.push_back(
State{t, simS, simV, simAcc, 
jerk});
 
 1721         Output result{newPos, newVelocity, newAcc, 
jerk};