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.
Dependencies: mbed
Motion.cpp
00001 /* 00002 * Motion.cpp 00003 * Copyright (c) 2018, 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 00603
Generated on Thu Jul 14 2022 09:49:36 by
