Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Motion.cpp
00001 /* 00002 * Motion.cpp 00003 * Copyright (c) 2020, ZHAW 00004 * All rights reserved. 00005 */ 00006 00007 #include <cmath> 00008 #include <algorithm> 00009 #include "Motion.h" 00010 00011 using namespace std; 00012 00013 const float Motion::DEFAULT_LIMIT = 1.0f; // default value for limits 00014 const float Motion::MINIMUM_LIMIT = 1.0e-9f; // smallest value allowed for limits 00015 00016 /** 00017 * Creates a <code>Motion</code> object. 00018 * The values for position, velocity and acceleration are set to 0. 00019 */ 00020 Motion::Motion() { 00021 00022 position = 0.0; 00023 velocity = 0.0f; 00024 00025 profileVelocity = DEFAULT_LIMIT; 00026 profileAcceleration = DEFAULT_LIMIT; 00027 profileDeceleration = DEFAULT_LIMIT; 00028 } 00029 00030 /** 00031 * Creates a <code>Motion</code> object with given values for position and velocity. 00032 * @param position the initial position value of this motion, given in [m] or [rad]. 00033 * @param velocity the initial velocity value of this motion, given in [m/s] or [rad/s]. 00034 */ 00035 Motion::Motion(double position, float velocity) { 00036 00037 this->position = position; 00038 this->velocity = velocity; 00039 00040 profileVelocity = DEFAULT_LIMIT; 00041 profileAcceleration = DEFAULT_LIMIT; 00042 profileDeceleration = DEFAULT_LIMIT; 00043 } 00044 00045 /** 00046 * Creates a <code>Motion</code> object with given values for position and velocity. 00047 * @param motion another <code>Motion</code> object to copy the values from. 00048 */ 00049 Motion::Motion(const Motion& motion) { 00050 00051 position = motion.position; 00052 velocity = motion.velocity; 00053 00054 profileVelocity = motion.profileVelocity; 00055 profileAcceleration = motion.profileAcceleration; 00056 profileDeceleration = motion.profileDeceleration; 00057 } 00058 00059 /** 00060 * Deletes the Motion object. 00061 */ 00062 Motion::~Motion() {} 00063 00064 /** 00065 * Sets the values for position and velocity. 00066 * @param position the desired position value of this motion, given in [m] or [rad]. 00067 * @param velocity the desired velocity value of this motion, given in [m/s] or [rad/s]. 00068 */ 00069 void Motion::set(double position, float velocity) { 00070 00071 this->position = position; 00072 this->velocity = velocity; 00073 } 00074 00075 /** 00076 * Sets the values for position and velocity. 00077 * @param motion another <code>Motion</code> object to copy the values from. 00078 */ 00079 void Motion::set(const Motion& motion) { 00080 00081 position = motion.position; 00082 velocity = motion.velocity; 00083 } 00084 00085 /** 00086 * Sets the position value. 00087 * @param position the desired position value of this motion, given in [m] or [rad]. 00088 */ 00089 void Motion::setPosition(double position) { 00090 00091 this->position = position; 00092 } 00093 00094 /** 00095 * Gets the position value. 00096 * @return the position value of this motion, given in [m] or [rad]. 00097 */ 00098 double Motion::getPosition() { 00099 00100 return position; 00101 } 00102 00103 /** 00104 * Sets the velocity value. 00105 * @param velocity the desired velocity value of this motion, given in [m/s] or [rad/s]. 00106 */ 00107 void Motion::setVelocity(float velocity) { 00108 00109 this->velocity = velocity; 00110 } 00111 00112 /** 00113 * Gets the velocity value. 00114 * @return the velocity value of this motion, given in [m/s] or [rad/s]. 00115 */ 00116 float Motion::getVelocity() { 00117 00118 return velocity; 00119 } 00120 00121 /** 00122 * Sets the limit for the velocity value. 00123 * @param profileVelocity the limit of the velocity. 00124 */ 00125 void Motion::setProfileVelocity(float profileVelocity) { 00126 00127 if (profileVelocity > MINIMUM_LIMIT) this->profileVelocity = profileVelocity; else this->profileVelocity = MINIMUM_LIMIT; 00128 } 00129 00130 /** 00131 * Sets the limit for the acceleration value. 00132 * @param profileAcceleration the limit of the acceleration. 00133 */ 00134 void Motion::setProfileAcceleration(float profileAcceleration) { 00135 00136 if (profileAcceleration > MINIMUM_LIMIT) this->profileAcceleration = profileAcceleration; else this->profileAcceleration = MINIMUM_LIMIT; 00137 } 00138 00139 /** 00140 * Sets the limit for the deceleration value. 00141 * @param profileDeceleration the limit of the deceleration. 00142 */ 00143 void Motion::setProfileDeceleration(float profileDeceleration) { 00144 00145 if (profileDeceleration > MINIMUM_LIMIT) this->profileDeceleration = profileDeceleration; else this->profileDeceleration = MINIMUM_LIMIT; 00146 } 00147 00148 /** 00149 * Sets the limits for velocity, acceleration and deceleration values. 00150 * @param profileVelocity the limit of the velocity. 00151 * @param profileAcceleration the limit of the acceleration. 00152 * @param profileDeceleration the limit of the deceleration. 00153 */ 00154 void Motion::setLimits(float profileVelocity, float profileAcceleration, float profileDeceleration) { 00155 00156 if (profileVelocity > MINIMUM_LIMIT) this->profileVelocity = profileVelocity; else this->profileVelocity = MINIMUM_LIMIT; 00157 if (profileAcceleration > MINIMUM_LIMIT) this->profileAcceleration = profileAcceleration; else this->profileAcceleration = MINIMUM_LIMIT; 00158 if (profileDeceleration > MINIMUM_LIMIT) this->profileDeceleration = profileDeceleration; else this->profileDeceleration = MINIMUM_LIMIT; 00159 } 00160 00161 /** 00162 * Gets the time needed to move to a given target position. 00163 * @param targetPosition the desired target position given in [m] or [rad]. 00164 * @return the time to move to the target position, given in [s]. 00165 */ 00166 float Motion::getTimeToPosition(double targetPosition) { 00167 00168 // calculate position, when velocity is reduced to zero 00169 00170 double stopPosition = (velocity > 0.0f) ? position+(double)(velocity*velocity/profileDeceleration*0.5f) : position-(double)(velocity*velocity/profileDeceleration*0.5f); 00171 00172 if (targetPosition > stopPosition) { // positive velocity required 00173 00174 if (velocity > profileVelocity) { // slow down to profile velocity first 00175 00176 float t1 = (velocity-profileVelocity)/profileDeceleration; 00177 float t2 = (float)(targetPosition-stopPosition)/profileVelocity; 00178 float t3 = profileVelocity/profileDeceleration; 00179 00180 return t1+t2+t3; 00181 00182 } else if (velocity > 0.0f) { // speed up to profile velocity 00183 00184 float t1 = (profileVelocity-velocity)/profileAcceleration; 00185 float t3 = profileVelocity/profileDeceleration; 00186 float t2 = ((float)(targetPosition-position)-(velocity+profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3; 00187 00188 if (t2 < 0.0f) { 00189 float maxVelocity = sqrt((2.0f*(float)(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration)); 00190 t1 = (maxVelocity-velocity)/profileAcceleration; 00191 t2 = 0.0f; 00192 t3 = maxVelocity/profileDeceleration; 00193 } 00194 00195 return t1+t2+t3; 00196 00197 } else { // slow down to zero first, and then speed up to profile velocity 00198 00199 float t1 = -velocity/profileDeceleration; 00200 float t2 = profileVelocity/profileAcceleration; 00201 float t4 = profileVelocity/profileDeceleration; 00202 float t3 = ((float)(targetPosition-position)-velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4); 00203 00204 if (t3 < 0.0f) { 00205 float maxVelocity = sqrt((2.0f*(float)(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration)); 00206 t2 = maxVelocity/profileAcceleration; 00207 t3 = 0.0f; 00208 t4 = maxVelocity/profileDeceleration; 00209 } 00210 00211 return t1+t2+t3+t4; 00212 } 00213 00214 } else { // negative velocity required 00215 00216 if (velocity < -profileVelocity) { // slow down to (negative) profile velocity first 00217 00218 float t1 = (-profileVelocity-velocity)/profileDeceleration; 00219 float t2 = (float)(stopPosition-targetPosition)/profileVelocity; 00220 float t3 = profileVelocity/profileDeceleration; 00221 00222 return t1+t2+t3; 00223 00224 } else if (velocity < 0.0f) { // speed up to (negative) profile velocity 00225 00226 float t1 = (velocity+profileVelocity)/profileAcceleration; 00227 float t3 = profileVelocity/profileDeceleration; 00228 float t2 = ((float)(position-targetPosition)+(velocity-profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3; 00229 00230 if (t2 < 0.0f) { 00231 float minVelocity = -sqrt((-2.0f*(float)(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration)); 00232 t1 = (velocity-minVelocity)/profileAcceleration; 00233 t2 = 0.0f; 00234 t3 = -minVelocity/profileDeceleration; 00235 } 00236 00237 return t1+t2+t3; 00238 00239 } else { // slow down to zero first, and then speed up to (negative) profile velocity 00240 00241 float t1 = velocity/profileDeceleration; 00242 float t2 = profileVelocity/profileAcceleration; 00243 float t4 = profileVelocity/profileDeceleration; 00244 float t3 = (-(float)(targetPosition-position)+velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4); 00245 00246 if (t3 < 0.0f) { 00247 float minVelocity = -sqrt((-2.0f*(float)(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration)); 00248 t2 = -minVelocity/profileAcceleration; 00249 t3 = 0.0f; 00250 t4 = -minVelocity/profileDeceleration; 00251 } 00252 00253 return t1+t2+t3+t4; 00254 } 00255 } 00256 } 00257 00258 /** 00259 * Increments the current motion towards a given target velocity. 00260 * @param targetVelocity the desired target velocity given in [m/s] or [rad/s]. 00261 * @param period the time period to increment the motion values for, given in [s]. 00262 */ 00263 void Motion::incrementToVelocity(float targetVelocity, float period) { 00264 00265 if (targetVelocity < -profileVelocity) targetVelocity = -profileVelocity; 00266 else if (targetVelocity > profileVelocity) targetVelocity = profileVelocity; 00267 00268 if (targetVelocity > 0.0f) { 00269 00270 if (velocity > targetVelocity) { // slow down to target velocity 00271 00272 float t1 = (velocity-targetVelocity)/profileDeceleration; 00273 00274 if (t1 > period) { 00275 position += (double)((velocity-profileDeceleration*0.5f*period)*period); 00276 velocity += -profileDeceleration*period; 00277 } else { 00278 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00279 velocity += -profileDeceleration*t1; 00280 position += (double)(velocity*(period-t1)); 00281 } 00282 00283 } else if (velocity > 0.0f) { // speed up to target velocity 00284 00285 float t1 = (targetVelocity-velocity)/profileAcceleration; 00286 00287 if (t1 > period) { 00288 position += (double)((velocity+profileAcceleration*0.5f*period)*period); 00289 velocity += profileAcceleration*period; 00290 } else { 00291 position += (double)((velocity+profileAcceleration*0.5f*t1)*t1); 00292 velocity += profileAcceleration*t1; 00293 position += (double)(velocity*(period-t1)); 00294 } 00295 00296 } else { // slow down to zero first, and then speed up to target velocity 00297 00298 float t1 = -velocity/profileDeceleration; 00299 float t2 = targetVelocity/profileAcceleration; 00300 00301 if (t1 > period) { 00302 position += (double)((velocity+profileDeceleration*0.5f*period)*period); 00303 velocity += profileDeceleration*period; 00304 } else if (t1+t2 > period) { 00305 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00306 velocity += profileDeceleration*t1; 00307 position += (double)((velocity+profileAcceleration*0.5f*(period-t1))*(period-t1)); 00308 velocity += profileAcceleration*(period-t1); 00309 } else { 00310 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00311 velocity += profileDeceleration*t1; 00312 position += (double)((velocity+profileAcceleration*0.5f*t2)*t2); 00313 velocity += profileAcceleration*t2; 00314 position += (double)(velocity*(period-t1-t2)); 00315 } 00316 } 00317 00318 } else { 00319 00320 if (velocity < targetVelocity) { // slow down to (negative) target velocity 00321 00322 float t1 = (targetVelocity-velocity)/profileDeceleration; 00323 00324 if (t1 > period) { 00325 position += (double)((velocity+profileDeceleration*0.5f*period)*period); 00326 velocity += profileDeceleration*period; 00327 } else { 00328 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00329 velocity += profileDeceleration*t1; 00330 position += (double)(velocity*(period-t1)); 00331 } 00332 00333 } else if (velocity < 0.0f) { // speed up to (negative) target velocity 00334 00335 float t1 = (velocity-targetVelocity)/profileAcceleration; 00336 00337 if (t1 > period) { 00338 position += (double)((velocity-profileAcceleration*0.5f*period)*period); 00339 velocity += -profileAcceleration*period; 00340 } else { 00341 position += (double)((velocity-profileAcceleration*0.5f*t1)*t1); 00342 velocity += -profileAcceleration*t1; 00343 position += (double)(velocity*(period-t1)); 00344 } 00345 00346 } else { // slow down to zero first, and then speed up to (negative) target velocity 00347 00348 float t1 = velocity/profileDeceleration; 00349 float t2 = -targetVelocity/profileAcceleration; 00350 00351 if (t1 > period) { 00352 position += (double)((velocity-profileDeceleration*0.5f*period)*period); 00353 velocity += -profileDeceleration*period; 00354 } else if (t1+t2 > period) { 00355 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00356 velocity += -profileDeceleration*t1; 00357 position += (double)((velocity-profileAcceleration*0.5f*(period-t1))*(period-t1)); 00358 velocity += -profileAcceleration*(period-t1); 00359 } else { 00360 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00361 velocity += -profileDeceleration*t1; 00362 position += (double)((velocity-profileAcceleration*0.5f*t2)*t2); 00363 velocity += -profileAcceleration*t2; 00364 position += (double)(velocity*(period-t1-t2)); 00365 } 00366 } 00367 } 00368 } 00369 00370 /** 00371 * Increments the current motion towards a given target position. 00372 * @param targetPosition the desired target position given in [m] or [rad]. 00373 * @param period the time period to increment the motion values for, given in [s]. 00374 */ 00375 void Motion::incrementToPosition(double targetPosition, float period) { 00376 00377 // calculate position, when velocity is reduced to zero 00378 00379 double stopPosition = (velocity > 0.0f) ? position+(double)(velocity*velocity/profileDeceleration*0.5f) : position-(double)(velocity*velocity/profileDeceleration*0.5f); 00380 00381 if (targetPosition > stopPosition) { // positive velocity required 00382 00383 if (velocity > profileVelocity) { // slow down to profile velocity first 00384 00385 float t1 = (velocity-profileVelocity)/profileDeceleration; 00386 float t2 = (float)(targetPosition-stopPosition)/profileVelocity; 00387 float t3 = profileVelocity/profileDeceleration; 00388 00389 if (t1 > period) { 00390 position += (double)((velocity-profileDeceleration*0.5f*period)*period); 00391 velocity += -profileDeceleration*period; 00392 } else if (t1+t2 > period) { 00393 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00394 velocity += -profileDeceleration*t1; 00395 position += (double)(velocity*(period-t1)); 00396 } else if (t1+t2+t3 > period) { 00397 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00398 velocity += -profileDeceleration*t1; 00399 position += (double)(velocity*t2); 00400 position += (double)((velocity-profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2)); 00401 velocity += -profileDeceleration*(period-t1-t2); 00402 } else { 00403 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00404 velocity += -profileDeceleration*t1; 00405 position += (double)(velocity*t2); 00406 position += (double)((velocity-profileDeceleration*0.5f*t3)*t3); 00407 velocity += -profileDeceleration*t3; 00408 } 00409 00410 } else if (velocity > 0.0f) { // speed up to profile velocity 00411 00412 float t1 = (profileVelocity-velocity)/profileAcceleration; 00413 float t3 = profileVelocity/profileDeceleration; 00414 float t2 = ((float)(targetPosition-position)-(velocity+profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3; 00415 00416 if (t2 < 0.0f) { 00417 float maxVelocity = sqrt((2.0f*(float)(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration)); 00418 t1 = (maxVelocity-velocity)/profileAcceleration; 00419 t2 = 0.0f; 00420 t3 = maxVelocity/profileDeceleration; 00421 } 00422 00423 if (t1 > period) { 00424 position += (double)((velocity+profileAcceleration*0.5f*period)*period); 00425 velocity += profileAcceleration*period; 00426 } else if (t1+t2 > period) { 00427 position += (double)((velocity+profileAcceleration*0.5f*t1)*t1); 00428 velocity += profileAcceleration*t1; 00429 position += (double)(velocity*(period-t1)); 00430 } else if (t1+t2+t3 > period) { 00431 position += (double)((velocity+profileAcceleration*0.5f*t1)*t1); 00432 velocity += profileAcceleration*t1; 00433 position += (double)(velocity*t2); 00434 position += (double)((velocity-profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2)); 00435 velocity += -profileDeceleration*(period-t1-t2); 00436 } else { 00437 position += (double)((velocity+profileAcceleration*0.5f*t1)*t1); 00438 velocity += profileAcceleration*t1; 00439 position += (double)(velocity*t2); 00440 position += (double)((velocity-profileDeceleration*0.5f*t3)*t3); 00441 velocity += -profileDeceleration*t3; 00442 } 00443 00444 } else { // slow down to zero first, and then speed up to profile velocity 00445 00446 float t1 = -velocity/profileDeceleration; 00447 float t2 = profileVelocity/profileAcceleration; 00448 float t4 = profileVelocity/profileDeceleration; 00449 float t3 = ((float)(targetPosition-position)-velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4); 00450 00451 if (t3 < 0.0f) { 00452 float maxVelocity = sqrt((2.0f*(float)(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration)); 00453 t2 = maxVelocity/profileAcceleration; 00454 t3 = 0.0f; 00455 t4 = maxVelocity/profileDeceleration; 00456 } 00457 00458 if (t1 > period) { 00459 position += (double)((velocity+profileDeceleration*0.5f*period)*period); 00460 velocity += profileDeceleration*period; 00461 } else if (t1+t2 > period) { 00462 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00463 velocity += profileDeceleration*t1; 00464 position += (double)((velocity+profileAcceleration*0.5f*(period-t1))*(period-t1)); 00465 velocity += profileAcceleration*(period-t1); 00466 } else if (t1+t2+t3 > period) { 00467 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00468 velocity += profileDeceleration*t1; 00469 position += (double)((velocity+profileAcceleration*0.5f*t2)*t2); 00470 velocity += profileAcceleration*t2; 00471 position += (double)(velocity*(period-t1-t2)); 00472 } else if (t1+t2+t3+t4 > period) { 00473 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00474 velocity += profileDeceleration*t1; 00475 position += (double)((velocity+profileAcceleration*0.5f*t2)*t2); 00476 velocity += profileAcceleration*t2; 00477 position += (double)(velocity*t3); 00478 position += (double)((velocity-profileDeceleration*0.5f*(period-t1-t2-t3))*(period-t1-t2-t3)); 00479 velocity += -profileDeceleration*(period-t1-t2-t3); 00480 } else { 00481 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00482 velocity += profileDeceleration*t1; 00483 position += (double)((velocity+profileAcceleration*0.5f*t2)*t2); 00484 velocity += profileAcceleration*t2; 00485 position += (double)(velocity*t3); 00486 position += (double)((velocity-profileDeceleration*0.5f*t4)*t4); 00487 velocity += -profileDeceleration*t4; 00488 } 00489 } 00490 00491 } else { // negative velocity required 00492 00493 if (velocity < -profileVelocity) { // slow down to (negative) profile velocity first 00494 00495 float t1 = (-profileVelocity-velocity)/profileDeceleration; 00496 float t2 = (float)(stopPosition-targetPosition)/profileVelocity; 00497 float t3 = profileVelocity/profileDeceleration; 00498 00499 if (t1 > period) { 00500 position += (double)((velocity+profileDeceleration*0.5f*period)*period); 00501 velocity += profileDeceleration*period; 00502 } else if (t1+t2 > period) { 00503 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00504 velocity += profileDeceleration*t1; 00505 position += (double)(velocity*(period-t1)); 00506 } else if (t1+t2+t3 > period) { 00507 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00508 velocity += profileDeceleration*t1; 00509 position += (double)(velocity*t2); 00510 position += (double)((velocity+profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2)); 00511 velocity += profileDeceleration*(period-t1-t2); 00512 } else { 00513 position += (double)((velocity+profileDeceleration*0.5f*t1)*t1); 00514 velocity += profileDeceleration*t1; 00515 position += (double)(velocity*t2); 00516 position += (double)((velocity+profileDeceleration*0.5f*t3)*t3); 00517 velocity += profileDeceleration*t3; 00518 } 00519 00520 } else if (velocity < 0.0f) { // speed up to (negative) profile velocity 00521 00522 float t1 = (velocity+profileVelocity)/profileAcceleration; 00523 float t3 = profileVelocity/profileDeceleration; 00524 float t2 = ((float)(position-targetPosition)+(velocity-profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3; 00525 00526 if (t2 < 0.0f) { 00527 float minVelocity = -sqrt((-2.0f*(float)(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration)); 00528 t1 = (velocity-minVelocity)/profileAcceleration; 00529 t2 = 0.0f; 00530 t3 = -minVelocity/profileDeceleration; 00531 } 00532 00533 if (t1 > period) { 00534 position += (double)((velocity-profileAcceleration*0.5f*period)*period); 00535 velocity += -profileAcceleration*period; 00536 } else if (t1+t2 > period) { 00537 position += (double)((velocity-profileAcceleration*0.5f*t1)*t1); 00538 velocity += -profileAcceleration*t1; 00539 position += (double)(velocity*(period-t1)); 00540 } else if (t1+t2+t3 > period) { 00541 position += (double)((velocity-profileAcceleration*0.5f*t1)*t1); 00542 velocity += -profileAcceleration*t1; 00543 position += (double)(velocity*t2); 00544 position += (double)((velocity+profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2)); 00545 velocity += profileDeceleration*(period-t1-t2); 00546 } else { 00547 position += (double)((velocity-profileAcceleration*0.5f*t1)*t1); 00548 velocity += -profileAcceleration*t1; 00549 position += (double)(velocity*t2); 00550 position += (double)((velocity+profileDeceleration*0.5f*t3)*t3); 00551 velocity += profileDeceleration*t3; 00552 } 00553 00554 } else { // slow down to zero first, and then speed up to (negative) profile velocity 00555 00556 float t1 = velocity/profileDeceleration; 00557 float t2 = profileVelocity/profileAcceleration; 00558 float t4 = profileVelocity/profileDeceleration; 00559 float t3 = (-(float)(targetPosition-position)+velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4); 00560 00561 if (t3 < 0.0f) { 00562 float minVelocity = -sqrt((-2.0f*(float)(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration)); 00563 t2 = -minVelocity/profileAcceleration; 00564 t3 = 0.0f; 00565 t4 = -minVelocity/profileDeceleration; 00566 } 00567 00568 if (t1 > period) { 00569 position += (double)((velocity-profileDeceleration*0.5f*period)*period); 00570 velocity += -profileDeceleration*period; 00571 } else if (t1+t2 > period) { 00572 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00573 velocity += -profileDeceleration*t1; 00574 position += (double)((velocity-profileAcceleration*0.5f*(period-t1))*(period-t1)); 00575 velocity += -profileAcceleration*(period-t1); 00576 } else if (t1+t2+t3 > period) { 00577 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00578 velocity += -profileDeceleration*t1; 00579 position += (double)((velocity-profileAcceleration*0.5f*t2)*t2); 00580 velocity += -profileAcceleration*t2; 00581 position += (double)(velocity*(period-t1-t2)); 00582 } else if (t1+t2+t3+t4 > period) { 00583 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00584 velocity += -profileDeceleration*t1; 00585 position += (double)((velocity-profileAcceleration*0.5f*t2)*t2); 00586 velocity += -profileAcceleration*t2; 00587 position += (double)(velocity*t3); 00588 position += (double)((velocity+profileDeceleration*0.5f*(period-t1-t2-t3))*(period-t1-t2-t3)); 00589 velocity += profileDeceleration*(period-t1-t2-t3); 00590 } else { 00591 position += (double)((velocity-profileDeceleration*0.5f*t1)*t1); 00592 velocity += -profileDeceleration*t1; 00593 position += (double)((velocity-profileAcceleration*0.5f*t2)*t2); 00594 velocity += -profileAcceleration*t2; 00595 position += (double)(velocity*t3); 00596 position += (double)((velocity+profileDeceleration*0.5f*t4)*t4); 00597 velocity += profileDeceleration*t4; 00598 } 00599 } 00600 } 00601 } 00602
Generated on Sat Jul 23 2022 17:01:00 by
