altb_pmic / Mbed 2 deprecated Test_Realbot

Dependencies:   mbed

Committer:
pmic
Date:
Thu Dec 05 09:09:31 2019 +0000
Revision:
4:52d2d31a7347
Parent:
3:e6d345973797
Use original (not adjusted) Motion class from Marcel -> correct results for getTimeToPosition (no problem with complex numbers??? <- we dont care right know and just accept it).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pmic 3:e6d345973797 1 /*
pmic 3:e6d345973797 2 * Motion.cpp
pmic 3:e6d345973797 3 * Copyright (c) 2017, ZHAW
pmic 3:e6d345973797 4 * All rights reserved.
pmic 3:e6d345973797 5 *
pmic 3:e6d345973797 6 * Created on: 02.02.2017
pmic 3:e6d345973797 7 * Author: Marcel Honegger
pmic 3:e6d345973797 8 */
pmic 3:e6d345973797 9
pmic 3:e6d345973797 10 #include <cmath>
pmic 3:e6d345973797 11 #include <algorithm>
pmic 3:e6d345973797 12 #include "Motion.h"
pmic 3:e6d345973797 13
pmic 4:52d2d31a7347 14 using namespace std;
pmic 4:52d2d31a7347 15
pmic 3:e6d345973797 16 const float Motion::DEFAULT_LIMIT = 1.0f; // default value for limits
pmic 3:e6d345973797 17 const float Motion::MINIMUM_LIMIT = 1.0e-6f; // smallest value allowed for limits
pmic 3:e6d345973797 18
pmic 3:e6d345973797 19 /**
pmic 3:e6d345973797 20 * Creates a <code>Motion</code> object.
pmic 3:e6d345973797 21 * The values for position, velocity and acceleration are set to 0.
pmic 3:e6d345973797 22 */
pmic 3:e6d345973797 23 Motion::Motion() {
pmic 4:52d2d31a7347 24
pmic 4:52d2d31a7347 25 position = 0.0;
pmic 4:52d2d31a7347 26 velocity = 0.0f;
pmic 4:52d2d31a7347 27 acceleration = 0.0f;
pmic 4:52d2d31a7347 28
pmic 4:52d2d31a7347 29 profileVelocity = DEFAULT_LIMIT;
pmic 4:52d2d31a7347 30 profileAcceleration = DEFAULT_LIMIT;
pmic 4:52d2d31a7347 31 profileDeceleration = DEFAULT_LIMIT;
pmic 3:e6d345973797 32 }
pmic 3:e6d345973797 33
pmic 3:e6d345973797 34 /**
pmic 3:e6d345973797 35 * Creates a <code>Motion</code> object with given values for position and velocity.
pmic 3:e6d345973797 36 * @param position the initial position value of this motion, given in [m] or [rad].
pmic 3:e6d345973797 37 * @param velocity the initial velocity value of this motion, given in [m/s] or [rad/s].
pmic 3:e6d345973797 38 */
pmic 3:e6d345973797 39 Motion::Motion(double position, float velocity) {
pmic 4:52d2d31a7347 40
pmic 4:52d2d31a7347 41 this->position = position;
pmic 4:52d2d31a7347 42 this->velocity = velocity;
pmic 4:52d2d31a7347 43 this->acceleration = 0.0f;
pmic 4:52d2d31a7347 44
pmic 4:52d2d31a7347 45 profileVelocity = DEFAULT_LIMIT;
pmic 4:52d2d31a7347 46 profileAcceleration = DEFAULT_LIMIT;
pmic 4:52d2d31a7347 47 profileDeceleration = DEFAULT_LIMIT;
pmic 3:e6d345973797 48 }
pmic 3:e6d345973797 49
pmic 3:e6d345973797 50 /**
pmic 3:e6d345973797 51 * Creates a <code>Motion</code> object with given values for position, velocity and acceleration.
pmic 3:e6d345973797 52 * @param position the initial position value of this motion, given in [m] or [rad].
pmic 3:e6d345973797 53 * @param velocity the initial velocity value of this motion, given in [m/s] or [rad/s].
pmic 3:e6d345973797 54 * @param acceleration the initial acceleration value of this motion, given in [m/s&sup2;] or [rad/s&sup2;].
pmic 3:e6d345973797 55 */
pmic 3:e6d345973797 56 Motion::Motion(double position, float velocity, float acceleration) {
pmic 4:52d2d31a7347 57
pmic 4:52d2d31a7347 58 this->position = position;
pmic 4:52d2d31a7347 59 this->velocity = velocity;
pmic 4:52d2d31a7347 60 this->acceleration = acceleration;
pmic 4:52d2d31a7347 61
pmic 4:52d2d31a7347 62 profileVelocity = DEFAULT_LIMIT;
pmic 4:52d2d31a7347 63 profileAcceleration = DEFAULT_LIMIT;
pmic 4:52d2d31a7347 64 profileDeceleration = DEFAULT_LIMIT;
pmic 3:e6d345973797 65 }
pmic 3:e6d345973797 66
pmic 3:e6d345973797 67 /**
pmic 3:e6d345973797 68 * Creates a <code>Motion</code> object with given values for position, velocity and acceleration.
pmic 3:e6d345973797 69 * @param position the initial position value of this motion, given in [m] or [rad].
pmic 3:e6d345973797 70 * @param velocity the initial velocity value of this motion, given in [m/s] or [rad/s].
pmic 3:e6d345973797 71 * @param profileVelocity the limit of the velocity.
pmic 3:e6d345973797 72 * @param profileAcceleration the limit of the acceleration.
pmic 3:e6d345973797 73 * @param profileDeceleration equal to profileAcceleration.
pmic 3:e6d345973797 74 */
pmic 3:e6d345973797 75 Motion::Motion(double position, float velocity, float profileVelocity, float profileAcceleration) {
pmic 3:e6d345973797 76
pmic 3:e6d345973797 77 this->position = position;
pmic 3:e6d345973797 78 this->velocity = velocity;
pmic 3:e6d345973797 79 this->acceleration = 0.0f;
pmic 3:e6d345973797 80
pmic 3:e6d345973797 81 this->profileVelocity = profileVelocity;
pmic 3:e6d345973797 82 this->profileAcceleration = profileAcceleration;
pmic 3:e6d345973797 83 this->profileDeceleration = profileAcceleration;
pmic 3:e6d345973797 84 }
pmic 3:e6d345973797 85
pmic 3:e6d345973797 86 /**
pmic 3:e6d345973797 87 * Creates a <code>Motion</code> object with given values for position and velocity.
pmic 3:e6d345973797 88 * @param motion another <code>Motion</code> object to copy the values from.
pmic 3:e6d345973797 89 */
pmic 3:e6d345973797 90 Motion::Motion(const Motion& motion) {
pmic 4:52d2d31a7347 91
pmic 4:52d2d31a7347 92 position = motion.position;
pmic 4:52d2d31a7347 93 velocity = motion.velocity;
pmic 4:52d2d31a7347 94 acceleration = motion.acceleration;
pmic 4:52d2d31a7347 95
pmic 4:52d2d31a7347 96 profileVelocity = motion.profileVelocity;
pmic 4:52d2d31a7347 97 profileAcceleration = motion.profileAcceleration;
pmic 4:52d2d31a7347 98 profileDeceleration = motion.profileDeceleration;
pmic 3:e6d345973797 99 }
pmic 3:e6d345973797 100
pmic 3:e6d345973797 101 Motion::~Motion() {}
pmic 3:e6d345973797 102
pmic 3:e6d345973797 103 /**
pmic 3:e6d345973797 104 * Sets the values for position and velocity.
pmic 3:e6d345973797 105 * @param position the desired position value of this motion, given in [m] or [rad].
pmic 3:e6d345973797 106 * @param velocity the desired velocity value of this motion, given in [m/s] or [rad/s].
pmic 3:e6d345973797 107 */
pmic 3:e6d345973797 108 void Motion::set(double position, float velocity) {
pmic 4:52d2d31a7347 109
pmic 4:52d2d31a7347 110 this->position = position;
pmic 4:52d2d31a7347 111 this->velocity = velocity;
pmic 3:e6d345973797 112 }
pmic 3:e6d345973797 113
pmic 3:e6d345973797 114 /**
pmic 3:e6d345973797 115 * Sets the values for position, velocity and acceleration.
pmic 3:e6d345973797 116 * @param position the desired position value of this motion, given in [m] or [rad].
pmic 3:e6d345973797 117 * @param velocity the desired velocity value of this motion, given in [m/s] or [rad/s].
pmic 3:e6d345973797 118 * @param acceleration the desired acceleration value of this motion, given in [m/s&sup2;] or [rad/s&sup2;].
pmic 3:e6d345973797 119 */
pmic 3:e6d345973797 120 void Motion::set(double position, float velocity, float acceleration) {
pmic 4:52d2d31a7347 121
pmic 4:52d2d31a7347 122 this->position = position;
pmic 4:52d2d31a7347 123 this->velocity = velocity;
pmic 4:52d2d31a7347 124 this->acceleration = acceleration;
pmic 3:e6d345973797 125 }
pmic 3:e6d345973797 126
pmic 3:e6d345973797 127 /**
pmic 3:e6d345973797 128 * Sets the values for position, velocity and acceleration.
pmic 3:e6d345973797 129 * @param motion another <code>Motion</code> object to copy the values from.
pmic 3:e6d345973797 130 */
pmic 3:e6d345973797 131 void Motion::set(const Motion& motion) {
pmic 4:52d2d31a7347 132
pmic 4:52d2d31a7347 133 position = motion.position;
pmic 4:52d2d31a7347 134 velocity = motion.velocity;
pmic 4:52d2d31a7347 135 acceleration = motion.acceleration;
pmic 3:e6d345973797 136 }
pmic 3:e6d345973797 137
pmic 3:e6d345973797 138 /**
pmic 3:e6d345973797 139 * Sets the position value.
pmic 3:e6d345973797 140 * @param position the desired position value of this motion, given in [m] or [rad].
pmic 3:e6d345973797 141 */
pmic 3:e6d345973797 142 void Motion::setPosition(double position) {
pmic 4:52d2d31a7347 143
pmic 4:52d2d31a7347 144 this->position = position;
pmic 3:e6d345973797 145 }
pmic 3:e6d345973797 146
pmic 3:e6d345973797 147 /**
pmic 3:e6d345973797 148 * Gets the position value.
pmic 3:e6d345973797 149 * @return the position value of this motion, given in [m] or [rad].
pmic 3:e6d345973797 150 */
pmic 3:e6d345973797 151 double Motion::getPosition() {
pmic 4:52d2d31a7347 152
pmic 4:52d2d31a7347 153 return position;
pmic 3:e6d345973797 154 }
pmic 3:e6d345973797 155
pmic 3:e6d345973797 156 /**
pmic 3:e6d345973797 157 * Sets the velocity value.
pmic 3:e6d345973797 158 * @param velocity the desired velocity value of this motion, given in [m/s] or [rad/s].
pmic 3:e6d345973797 159 */
pmic 3:e6d345973797 160 void Motion::setVelocity(float velocity) {
pmic 4:52d2d31a7347 161
pmic 4:52d2d31a7347 162 this->velocity = velocity;
pmic 3:e6d345973797 163 }
pmic 3:e6d345973797 164
pmic 3:e6d345973797 165 /**
pmic 3:e6d345973797 166 * Gets the velocity value.
pmic 3:e6d345973797 167 * @return the velocity value of this motion, given in [m/s] or [rad/s].
pmic 3:e6d345973797 168 */
pmic 3:e6d345973797 169 float Motion::getVelocity() {
pmic 4:52d2d31a7347 170
pmic 4:52d2d31a7347 171 return velocity;
pmic 3:e6d345973797 172 }
pmic 3:e6d345973797 173
pmic 3:e6d345973797 174 /**
pmic 3:e6d345973797 175 * Sets the acceleration value.
pmic 3:e6d345973797 176 * @param acceleration the desired acceleration value of this motion, given in [m/s&sup2;] or [rad/s&sup2;].
pmic 3:e6d345973797 177 */
pmic 3:e6d345973797 178 void Motion::setAcceleration(float acceleration) {
pmic 4:52d2d31a7347 179
pmic 4:52d2d31a7347 180 this->acceleration = acceleration;
pmic 3:e6d345973797 181 }
pmic 3:e6d345973797 182
pmic 3:e6d345973797 183 /**
pmic 3:e6d345973797 184 * Gets the acceleration value.
pmic 3:e6d345973797 185 * @return the acceleration value of this motion, given in [m/s&sup2;] or [rad/s&sup2;].
pmic 3:e6d345973797 186 */
pmic 3:e6d345973797 187 float Motion::getAcceleration() {
pmic 4:52d2d31a7347 188
pmic 4:52d2d31a7347 189 return acceleration;
pmic 3:e6d345973797 190 }
pmic 3:e6d345973797 191
pmic 3:e6d345973797 192 /**
pmic 3:e6d345973797 193 * Sets the limit for the velocity value.
pmic 3:e6d345973797 194 * @param profileVelocity the limit of the velocity.
pmic 3:e6d345973797 195 */
pmic 3:e6d345973797 196 void Motion::setProfileVelocity(float profileVelocity) {
pmic 4:52d2d31a7347 197
pmic 4:52d2d31a7347 198 if (profileVelocity > MINIMUM_LIMIT) this->profileVelocity = profileVelocity; else this->profileVelocity = MINIMUM_LIMIT;
pmic 3:e6d345973797 199 }
pmic 3:e6d345973797 200
pmic 3:e6d345973797 201 /**
pmic 3:e6d345973797 202 * Sets the limit for the acceleration value.
pmic 3:e6d345973797 203 * @param profileAcceleration the limit of the acceleration.
pmic 3:e6d345973797 204 */
pmic 3:e6d345973797 205 void Motion::setProfileAcceleration(float profileAcceleration) {
pmic 4:52d2d31a7347 206
pmic 4:52d2d31a7347 207 if (profileAcceleration > MINIMUM_LIMIT) this->profileAcceleration = profileAcceleration; else this->profileAcceleration = MINIMUM_LIMIT;
pmic 3:e6d345973797 208 }
pmic 3:e6d345973797 209
pmic 3:e6d345973797 210 /**
pmic 3:e6d345973797 211 * Sets the limit for the deceleration value.
pmic 3:e6d345973797 212 * @param profileDeceleration the limit of the deceleration.
pmic 3:e6d345973797 213 */
pmic 3:e6d345973797 214 void Motion::setProfileDeceleration(float profileDeceleration) {
pmic 4:52d2d31a7347 215
pmic 4:52d2d31a7347 216 if (profileDeceleration > MINIMUM_LIMIT) this->profileDeceleration = profileDeceleration; else this->profileDeceleration = MINIMUM_LIMIT;
pmic 3:e6d345973797 217 }
pmic 3:e6d345973797 218
pmic 3:e6d345973797 219 /**
pmic 3:e6d345973797 220 * Sets the limits for velocity, acceleration and deceleration values.
pmic 3:e6d345973797 221 * @param profileVelocity the limit of the velocity.
pmic 3:e6d345973797 222 * @param profileAcceleration the limit of the acceleration.
pmic 3:e6d345973797 223 * @param profileDeceleration the limit of the deceleration.
pmic 3:e6d345973797 224 */
pmic 3:e6d345973797 225 void Motion::setLimits(float profileVelocity, float profileAcceleration, float profileDeceleration) {
pmic 4:52d2d31a7347 226
pmic 4:52d2d31a7347 227 if (profileVelocity > MINIMUM_LIMIT) this->profileVelocity = profileVelocity; else this->profileVelocity = MINIMUM_LIMIT;
pmic 4:52d2d31a7347 228 if (profileAcceleration > MINIMUM_LIMIT) this->profileAcceleration = profileAcceleration; else this->profileAcceleration = MINIMUM_LIMIT;
pmic 4:52d2d31a7347 229 if (profileDeceleration > MINIMUM_LIMIT) this->profileDeceleration = profileDeceleration; else this->profileDeceleration = MINIMUM_LIMIT;
pmic 3:e6d345973797 230 }
pmic 3:e6d345973797 231
pmic 3:e6d345973797 232 /**
pmic 3:e6d345973797 233 * Gets the time needed to move to a given target position.
pmic 3:e6d345973797 234 * @param targetPosition the desired target position given in [m] or [rad].
pmic 3:e6d345973797 235 * @return the time to move to the target position, given in [s].
pmic 3:e6d345973797 236 */
pmic 3:e6d345973797 237 float Motion::getTimeToPosition(double targetPosition) {
pmic 4:52d2d31a7347 238
pmic 4:52d2d31a7347 239 // calculate position, when velocity is reduced to zero
pmic 4:52d2d31a7347 240
pmic 4:52d2d31a7347 241 double stopPosition = (velocity > 0.0f) ? position+static_cast<double>(velocity*velocity/profileDeceleration*0.5f) : position-static_cast<double>(velocity*velocity/profileDeceleration*0.5f);
pmic 4:52d2d31a7347 242
pmic 4:52d2d31a7347 243 if (targetPosition > stopPosition) { // positive velocity required
pmic 4:52d2d31a7347 244
pmic 4:52d2d31a7347 245 if (velocity > profileVelocity) { // slow down to profile velocity first
pmic 4:52d2d31a7347 246
pmic 4:52d2d31a7347 247 float t1 = (velocity-profileVelocity)/profileDeceleration;
pmic 4:52d2d31a7347 248 float t2 = static_cast<float>(targetPosition-stopPosition)/profileVelocity;
pmic 4:52d2d31a7347 249 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 250
pmic 4:52d2d31a7347 251 return t1+t2+t3;
pmic 4:52d2d31a7347 252
pmic 4:52d2d31a7347 253 } else if (velocity > 0.0f) { // speed up to profile velocity
pmic 4:52d2d31a7347 254
pmic 4:52d2d31a7347 255 float t1 = (profileVelocity-velocity)/profileAcceleration;
pmic 4:52d2d31a7347 256 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 257 float t2 = (static_cast<float>(targetPosition-position)-(velocity+profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3;
pmic 4:52d2d31a7347 258
pmic 4:52d2d31a7347 259 if (t2 < 0.0f) {
pmic 4:52d2d31a7347 260 float maxVelocity = sqrt((2.0f*static_cast<float>(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration));
pmic 4:52d2d31a7347 261 t1 = (maxVelocity-velocity)/profileAcceleration;
pmic 4:52d2d31a7347 262 t2 = 0.0f;
pmic 4:52d2d31a7347 263 t3 = maxVelocity/profileDeceleration;
pmic 4:52d2d31a7347 264 }
pmic 4:52d2d31a7347 265
pmic 4:52d2d31a7347 266 return t1+t2+t3;
pmic 4:52d2d31a7347 267
pmic 4:52d2d31a7347 268 } else { // slow down to zero first, and then speed up to profile velocity
pmic 4:52d2d31a7347 269
pmic 4:52d2d31a7347 270 float t1 = -velocity/profileDeceleration;
pmic 4:52d2d31a7347 271 float t2 = profileVelocity/profileAcceleration;
pmic 4:52d2d31a7347 272 float t4 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 273 float t3 = (static_cast<float>(targetPosition-position)-velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4);
pmic 4:52d2d31a7347 274
pmic 4:52d2d31a7347 275 if (t3 < 0.0f) {
pmic 4:52d2d31a7347 276 float maxVelocity = sqrt((2.0f*static_cast<float>(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration));
pmic 4:52d2d31a7347 277 t2 = maxVelocity/profileAcceleration;
pmic 4:52d2d31a7347 278 t3 = 0.0f;
pmic 4:52d2d31a7347 279 t4 = maxVelocity/profileDeceleration;
pmic 4:52d2d31a7347 280 }
pmic 4:52d2d31a7347 281
pmic 4:52d2d31a7347 282 return t1+t2+t3+t4;
pmic 4:52d2d31a7347 283 }
pmic 4:52d2d31a7347 284
pmic 4:52d2d31a7347 285 } else { // negative velocity required
pmic 4:52d2d31a7347 286
pmic 4:52d2d31a7347 287 if (velocity < -profileVelocity) { // slow down to (negative) profile velocity first
pmic 4:52d2d31a7347 288
pmic 4:52d2d31a7347 289 float t1 = (-profileVelocity-velocity)/profileDeceleration;
pmic 4:52d2d31a7347 290 float t2 = static_cast<float>(stopPosition-targetPosition)/profileVelocity;
pmic 4:52d2d31a7347 291 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 292
pmic 4:52d2d31a7347 293 return t1+t2+t3;
pmic 4:52d2d31a7347 294
pmic 4:52d2d31a7347 295 } else if (velocity < 0.0f) { // speed up to (negative) profile velocity
pmic 4:52d2d31a7347 296
pmic 4:52d2d31a7347 297 float t1 = (velocity+profileVelocity)/profileAcceleration;
pmic 4:52d2d31a7347 298 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 299 float t2 = (static_cast<float>(position-targetPosition)+(velocity-profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3;
pmic 4:52d2d31a7347 300
pmic 4:52d2d31a7347 301 if (t2 < 0.0f) {
pmic 4:52d2d31a7347 302 float minVelocity = -sqrt((-2.0f*static_cast<float>(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration));
pmic 4:52d2d31a7347 303 t1 = (velocity-minVelocity)/profileAcceleration;
pmic 4:52d2d31a7347 304 t2 = 0.0f;
pmic 4:52d2d31a7347 305 t3 = -minVelocity/profileDeceleration;
pmic 4:52d2d31a7347 306 }
pmic 4:52d2d31a7347 307
pmic 4:52d2d31a7347 308 return t1+t2+t3;
pmic 4:52d2d31a7347 309
pmic 4:52d2d31a7347 310 } else { // slow down to zero first, and then speed up to (negative) profile velocity
pmic 4:52d2d31a7347 311
pmic 4:52d2d31a7347 312 float t1 = velocity/profileDeceleration;
pmic 4:52d2d31a7347 313 float t2 = profileVelocity/profileAcceleration;
pmic 4:52d2d31a7347 314 float t4 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 315 float t3 = (-static_cast<float>(targetPosition-position)+velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4);
pmic 4:52d2d31a7347 316
pmic 4:52d2d31a7347 317 if (t3 < 0.0f) {
pmic 4:52d2d31a7347 318 float minVelocity = -sqrt((-2.0f*static_cast<float>(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration));
pmic 4:52d2d31a7347 319 t2 = -minVelocity/profileAcceleration;
pmic 4:52d2d31a7347 320 t3 = 0.0f;
pmic 4:52d2d31a7347 321 t4 = -minVelocity/profileDeceleration;
pmic 4:52d2d31a7347 322 }
pmic 4:52d2d31a7347 323
pmic 4:52d2d31a7347 324 return t1+t2+t3+t4;
pmic 4:52d2d31a7347 325 }
pmic 3:e6d345973797 326 }
pmic 3:e6d345973797 327 }
pmic 3:e6d345973797 328
pmic 3:e6d345973797 329 /**
pmic 3:e6d345973797 330 * Gets the distance moved until the velocity reaches zero.
pmic 3:e6d345973797 331 * @return the distance to the stop position.
pmic 3:e6d345973797 332 */
pmic 3:e6d345973797 333 double Motion::getDistanceToStop() {
pmic 4:52d2d31a7347 334
pmic 4:52d2d31a7347 335 return static_cast<double>(velocity*velocity/profileDeceleration*0.5f);
pmic 3:e6d345973797 336 }
pmic 3:e6d345973797 337
pmic 3:e6d345973797 338 /**
pmic 3:e6d345973797 339 * Increments the current motion towards a given target velocity.
pmic 3:e6d345973797 340 * @param targetVelocity the desired target velocity given in [m/s] or [rad/s].
pmic 3:e6d345973797 341 * @param period the time period to increment the motion values for, given in [s].
pmic 3:e6d345973797 342 */
pmic 3:e6d345973797 343 void Motion::incrementToVelocity(float targetVelocity, float period) {
pmic 4:52d2d31a7347 344
pmic 4:52d2d31a7347 345 if (targetVelocity < -profileVelocity) targetVelocity = -profileVelocity;
pmic 4:52d2d31a7347 346 else if (targetVelocity > profileVelocity) targetVelocity = profileVelocity;
pmic 4:52d2d31a7347 347
pmic 4:52d2d31a7347 348 if (targetVelocity > 0.0f) {
pmic 4:52d2d31a7347 349
pmic 4:52d2d31a7347 350 if (velocity > targetVelocity) { // slow down to target velocity
pmic 4:52d2d31a7347 351
pmic 4:52d2d31a7347 352 float t1 = (velocity-targetVelocity)/profileDeceleration;
pmic 4:52d2d31a7347 353
pmic 4:52d2d31a7347 354 if (t1 > period) {
pmic 4:52d2d31a7347 355 position += static_cast<double>((velocity-profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 356 velocity += -profileDeceleration*period;
pmic 4:52d2d31a7347 357 acceleration = -profileDeceleration;
pmic 4:52d2d31a7347 358 } else {
pmic 4:52d2d31a7347 359 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 360 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 361 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 362 acceleration = 0.0f;
pmic 4:52d2d31a7347 363 }
pmic 4:52d2d31a7347 364
pmic 4:52d2d31a7347 365 } else if (velocity > 0.0f) { // speed up to target velocity
pmic 4:52d2d31a7347 366
pmic 4:52d2d31a7347 367 float t1 = (targetVelocity-velocity)/profileAcceleration;
pmic 4:52d2d31a7347 368
pmic 4:52d2d31a7347 369 if (t1 > period) {
pmic 4:52d2d31a7347 370 position += static_cast<double>((velocity+profileAcceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 371 velocity += profileAcceleration*period;
pmic 4:52d2d31a7347 372 acceleration = profileAcceleration;
pmic 4:52d2d31a7347 373 } else {
pmic 4:52d2d31a7347 374 position += static_cast<double>((velocity+profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 375 velocity += profileAcceleration*t1;
pmic 4:52d2d31a7347 376 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 377 acceleration = 0.0f;
pmic 4:52d2d31a7347 378 }
pmic 4:52d2d31a7347 379
pmic 4:52d2d31a7347 380 } else { // slow down to zero first, and then speed up to target velocity
pmic 4:52d2d31a7347 381
pmic 4:52d2d31a7347 382 float t1 = -velocity/profileDeceleration;
pmic 4:52d2d31a7347 383 float t2 = targetVelocity/profileAcceleration;
pmic 4:52d2d31a7347 384
pmic 4:52d2d31a7347 385 if (t1 > period) {
pmic 4:52d2d31a7347 386 position += static_cast<double>((velocity+profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 387 velocity += profileDeceleration*period;
pmic 4:52d2d31a7347 388 acceleration = profileDeceleration;
pmic 4:52d2d31a7347 389 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 390 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 391 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 392 position += static_cast<double>((velocity+profileAcceleration*0.5f*(period-t1))*(period-t1));
pmic 4:52d2d31a7347 393 velocity += profileAcceleration*(period-t1);
pmic 4:52d2d31a7347 394 acceleration = profileAcceleration;
pmic 4:52d2d31a7347 395 } else {
pmic 4:52d2d31a7347 396 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 397 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 398 position += static_cast<double>((velocity+profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 399 velocity += profileAcceleration*t2;
pmic 4:52d2d31a7347 400 position += static_cast<double>(velocity*(period-t1-t2));
pmic 4:52d2d31a7347 401 acceleration = 0.0f;
pmic 4:52d2d31a7347 402 }
pmic 4:52d2d31a7347 403 }
pmic 4:52d2d31a7347 404
pmic 4:52d2d31a7347 405 } else {
pmic 4:52d2d31a7347 406
pmic 4:52d2d31a7347 407 if (velocity < targetVelocity) { // slow down to (negative) target velocity
pmic 4:52d2d31a7347 408
pmic 4:52d2d31a7347 409 float t1 = (targetVelocity-velocity)/profileDeceleration;
pmic 4:52d2d31a7347 410
pmic 4:52d2d31a7347 411 if (t1 > period) {
pmic 4:52d2d31a7347 412 position += static_cast<double>((velocity+profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 413 velocity += profileDeceleration*period;
pmic 4:52d2d31a7347 414 acceleration = profileDeceleration;
pmic 4:52d2d31a7347 415 } else {
pmic 4:52d2d31a7347 416 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 417 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 418 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 419 acceleration = 0.0f;
pmic 4:52d2d31a7347 420 }
pmic 4:52d2d31a7347 421
pmic 4:52d2d31a7347 422 } else if (velocity < 0.0f) { // speed up to (negative) target velocity
pmic 4:52d2d31a7347 423
pmic 4:52d2d31a7347 424 float t1 = (velocity-targetVelocity)/profileAcceleration;
pmic 4:52d2d31a7347 425
pmic 4:52d2d31a7347 426 if (t1 > period) {
pmic 4:52d2d31a7347 427 position += static_cast<double>((velocity-profileAcceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 428 velocity += -profileAcceleration*period;
pmic 4:52d2d31a7347 429 acceleration = -profileAcceleration;
pmic 4:52d2d31a7347 430 } else {
pmic 4:52d2d31a7347 431 position += static_cast<double>((velocity-profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 432 velocity += -profileAcceleration*t1;
pmic 4:52d2d31a7347 433 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 434 acceleration = 0.0f;
pmic 4:52d2d31a7347 435 }
pmic 4:52d2d31a7347 436
pmic 4:52d2d31a7347 437 } else { // slow down to zero first, and then speed up to (negative) target velocity
pmic 4:52d2d31a7347 438
pmic 4:52d2d31a7347 439 float t1 = velocity/profileDeceleration;
pmic 4:52d2d31a7347 440 float t2 = -targetVelocity/profileAcceleration;
pmic 4:52d2d31a7347 441
pmic 4:52d2d31a7347 442 if (t1 > period) {
pmic 4:52d2d31a7347 443 position += static_cast<double>((velocity-profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 444 velocity += -profileDeceleration*period;
pmic 4:52d2d31a7347 445 acceleration = -profileDeceleration;
pmic 4:52d2d31a7347 446 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 447 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 448 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 449 position += static_cast<double>((velocity-profileAcceleration*0.5f*(period-t1))*(period-t1));
pmic 4:52d2d31a7347 450 velocity += -profileAcceleration*(period-t1);
pmic 4:52d2d31a7347 451 acceleration = -profileAcceleration;
pmic 4:52d2d31a7347 452 } else {
pmic 4:52d2d31a7347 453 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 454 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 455 position += static_cast<double>((velocity-profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 456 velocity += -profileAcceleration*t2;
pmic 4:52d2d31a7347 457 position += static_cast<double>(velocity*(period-t1-t2));
pmic 4:52d2d31a7347 458 acceleration = 0.0f;
pmic 4:52d2d31a7347 459 }
pmic 4:52d2d31a7347 460 }
pmic 3:e6d345973797 461 }
pmic 3:e6d345973797 462 }
pmic 3:e6d345973797 463
pmic 3:e6d345973797 464 /**
pmic 3:e6d345973797 465 * Increments the current motion towards a given target position.
pmic 3:e6d345973797 466 * @param targetPosition the desired target position given in [m] or [rad].
pmic 3:e6d345973797 467 * @param period the time period to increment the motion values for, given in [s].
pmic 3:e6d345973797 468 */
pmic 3:e6d345973797 469 void Motion::incrementToPosition(double targetPosition, float period) {
pmic 4:52d2d31a7347 470
pmic 4:52d2d31a7347 471 // calculate position, when velocity is reduced to zero
pmic 4:52d2d31a7347 472
pmic 4:52d2d31a7347 473 double stopPosition = (velocity > 0.0f) ? position+static_cast<double>(velocity*velocity/profileDeceleration*0.5f) : position-static_cast<double>(velocity*velocity/profileDeceleration*0.5f);
pmic 4:52d2d31a7347 474
pmic 4:52d2d31a7347 475 if (targetPosition > stopPosition) { // positive velocity required
pmic 4:52d2d31a7347 476
pmic 4:52d2d31a7347 477 if (velocity > profileVelocity) { // slow down to profile velocity first
pmic 4:52d2d31a7347 478
pmic 4:52d2d31a7347 479 float t1 = (velocity-profileVelocity)/profileDeceleration;
pmic 4:52d2d31a7347 480 float t2 = static_cast<float>(targetPosition-stopPosition)/profileVelocity;
pmic 4:52d2d31a7347 481 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 482
pmic 4:52d2d31a7347 483 if (t1 > period) {
pmic 4:52d2d31a7347 484 position += static_cast<double>((velocity-profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 485 velocity += -profileDeceleration*period;
pmic 4:52d2d31a7347 486 acceleration = -profileDeceleration;
pmic 4:52d2d31a7347 487 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 488 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 489 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 490 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 491 acceleration = 0.0f;
pmic 4:52d2d31a7347 492 } else if (t1+t2+t3 > period) {
pmic 4:52d2d31a7347 493 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 494 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 495 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 496 position += static_cast<double>((velocity-profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2));
pmic 4:52d2d31a7347 497 velocity += -profileDeceleration*(period-t1-t2);
pmic 4:52d2d31a7347 498 acceleration = -profileDeceleration;
pmic 4:52d2d31a7347 499 } else {
pmic 4:52d2d31a7347 500 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 501 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 502 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 503 position += static_cast<double>((velocity-profileDeceleration*0.5f*t3)*t3);
pmic 4:52d2d31a7347 504 velocity += -profileDeceleration*t3;
pmic 4:52d2d31a7347 505 acceleration = 0.0f;
pmic 4:52d2d31a7347 506 }
pmic 4:52d2d31a7347 507
pmic 4:52d2d31a7347 508 } else if (velocity > 0.0f) { // speed up to profile velocity
pmic 4:52d2d31a7347 509
pmic 4:52d2d31a7347 510 float t1 = (profileVelocity-velocity)/profileAcceleration;
pmic 4:52d2d31a7347 511 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 512 float t2 = (static_cast<float>(targetPosition-position)-(velocity+profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3;
pmic 4:52d2d31a7347 513
pmic 4:52d2d31a7347 514 if (t2 < 0.0f) {
pmic 4:52d2d31a7347 515 float maxVelocity = sqrt((2.0f*static_cast<float>(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration));
pmic 3:e6d345973797 516 t1 = (maxVelocity-velocity)/profileAcceleration;
pmic 3:e6d345973797 517 t2 = 0.0f;
pmic 3:e6d345973797 518 t3 = maxVelocity/profileDeceleration;
pmic 3:e6d345973797 519 }
pmic 4:52d2d31a7347 520
pmic 4:52d2d31a7347 521 if (t1 > period) {
pmic 4:52d2d31a7347 522 position += static_cast<double>((velocity+profileAcceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 523 velocity += profileAcceleration*period;
pmic 4:52d2d31a7347 524 acceleration = profileAcceleration;
pmic 4:52d2d31a7347 525 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 526 position += static_cast<double>((velocity+profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 527 velocity += profileAcceleration*t1;
pmic 4:52d2d31a7347 528 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 529 acceleration = 0.0f;
pmic 4:52d2d31a7347 530 } else if (t1+t2+t3 > period) {
pmic 4:52d2d31a7347 531 position += static_cast<double>((velocity+profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 532 velocity += profileAcceleration*t1;
pmic 4:52d2d31a7347 533 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 534 position += static_cast<double>((velocity-profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2));
pmic 4:52d2d31a7347 535 velocity += -profileDeceleration*(period-t1-t2);
pmic 4:52d2d31a7347 536 acceleration = -profileDeceleration;
pmic 4:52d2d31a7347 537 } else {
pmic 4:52d2d31a7347 538 position += static_cast<double>((velocity+profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 539 velocity += profileAcceleration*t1;
pmic 4:52d2d31a7347 540 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 541 position += static_cast<double>((velocity-profileDeceleration*0.5f*t3)*t3);
pmic 4:52d2d31a7347 542 velocity += -profileDeceleration*t3;
pmic 4:52d2d31a7347 543 acceleration = 0.0f;
pmic 4:52d2d31a7347 544 }
pmic 4:52d2d31a7347 545
pmic 4:52d2d31a7347 546 } else { // slow down to zero first, and then speed up to profile velocity
pmic 4:52d2d31a7347 547
pmic 4:52d2d31a7347 548 float t1 = -velocity/profileDeceleration;
pmic 4:52d2d31a7347 549 float t2 = profileVelocity/profileAcceleration;
pmic 4:52d2d31a7347 550 float t4 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 551 float t3 = (static_cast<float>(targetPosition-position)-velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4);
pmic 4:52d2d31a7347 552
pmic 4:52d2d31a7347 553 if (t3 < 0.0f) {
pmic 4:52d2d31a7347 554 float maxVelocity = sqrt((2.0f*static_cast<float>(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration));
pmic 3:e6d345973797 555 t2 = maxVelocity/profileAcceleration;
pmic 3:e6d345973797 556 t3 = 0.0f;
pmic 3:e6d345973797 557 t4 = maxVelocity/profileDeceleration;
pmic 4:52d2d31a7347 558 }
pmic 4:52d2d31a7347 559
pmic 4:52d2d31a7347 560 if (t1 > period) {
pmic 4:52d2d31a7347 561 position += static_cast<double>((velocity+profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 562 velocity += profileDeceleration*period;
pmic 4:52d2d31a7347 563 acceleration = profileDeceleration;
pmic 4:52d2d31a7347 564 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 565 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 566 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 567 position += static_cast<double>((velocity+profileAcceleration*0.5f*(period-t1))*(period-t1));
pmic 4:52d2d31a7347 568 velocity += profileAcceleration*(period-t1);
pmic 4:52d2d31a7347 569 acceleration = profileAcceleration;
pmic 4:52d2d31a7347 570 } else if (t1+t2+t3 > period) {
pmic 4:52d2d31a7347 571 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 572 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 573 position += static_cast<double>((velocity+profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 574 velocity += profileAcceleration*t2;
pmic 4:52d2d31a7347 575 position += static_cast<double>(velocity*(period-t1-t2));
pmic 4:52d2d31a7347 576 acceleration = 0.0f;
pmic 4:52d2d31a7347 577 } else if (t1+t2+t3+t4 > period) {
pmic 4:52d2d31a7347 578 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 579 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 580 position += static_cast<double>((velocity+profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 581 velocity += profileAcceleration*t2;
pmic 4:52d2d31a7347 582 position += static_cast<double>(velocity*t3);
pmic 4:52d2d31a7347 583 position += static_cast<double>((velocity-profileDeceleration*0.5f*(period-t1-t2-t3))*(period-t1-t2-t3));
pmic 4:52d2d31a7347 584 velocity += -profileDeceleration*(period-t1-t2-t3);
pmic 4:52d2d31a7347 585 acceleration = -profileDeceleration;
pmic 4:52d2d31a7347 586 } else {
pmic 4:52d2d31a7347 587 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 588 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 589 position += static_cast<double>((velocity+profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 590 velocity += profileAcceleration*t2;
pmic 4:52d2d31a7347 591 position += static_cast<double>(velocity*t3);
pmic 4:52d2d31a7347 592 position += static_cast<double>((velocity-profileDeceleration*0.5f*t4)*t4);
pmic 4:52d2d31a7347 593 velocity += -profileDeceleration*t4;
pmic 4:52d2d31a7347 594 acceleration = 0.0f;
pmic 4:52d2d31a7347 595 }
pmic 3:e6d345973797 596 }
pmic 4:52d2d31a7347 597
pmic 4:52d2d31a7347 598 } else { // negative velocity required
pmic 4:52d2d31a7347 599
pmic 4:52d2d31a7347 600 if (velocity < -profileVelocity) { // slow down to (negative) profile velocity first
pmic 4:52d2d31a7347 601
pmic 4:52d2d31a7347 602 float t1 = (-profileVelocity-velocity)/profileDeceleration;
pmic 4:52d2d31a7347 603 float t2 = static_cast<float>(stopPosition-targetPosition)/profileVelocity;
pmic 4:52d2d31a7347 604 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 605
pmic 4:52d2d31a7347 606 if (t1 > period) {
pmic 4:52d2d31a7347 607 position += static_cast<double>((velocity+profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 608 velocity += profileDeceleration*period;
pmic 4:52d2d31a7347 609 acceleration = profileDeceleration;
pmic 4:52d2d31a7347 610 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 611 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 612 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 613 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 614 acceleration = 0.0f;
pmic 4:52d2d31a7347 615 } else if (t1+t2+t3 > period) {
pmic 4:52d2d31a7347 616 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 617 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 618 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 619 position += static_cast<double>((velocity+profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2));
pmic 4:52d2d31a7347 620 velocity += profileDeceleration*(period-t1-t2);
pmic 4:52d2d31a7347 621 acceleration = profileDeceleration;
pmic 4:52d2d31a7347 622 } else {
pmic 4:52d2d31a7347 623 position += static_cast<double>((velocity+profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 624 velocity += profileDeceleration*t1;
pmic 4:52d2d31a7347 625 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 626 position += static_cast<double>((velocity+profileDeceleration*0.5f*t3)*t3);
pmic 4:52d2d31a7347 627 velocity += profileDeceleration*t3;
pmic 4:52d2d31a7347 628 acceleration = 0.0f;
pmic 4:52d2d31a7347 629 }
pmic 4:52d2d31a7347 630
pmic 4:52d2d31a7347 631 } else if (velocity < 0.0f) { // speed up to (negative) profile velocity
pmic 4:52d2d31a7347 632
pmic 4:52d2d31a7347 633 float t1 = (velocity+profileVelocity)/profileAcceleration;
pmic 4:52d2d31a7347 634 float t3 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 635 float t2 = (static_cast<float>(position-targetPosition)+(velocity-profileVelocity)*0.5f*t1)/profileVelocity-0.5f*t3;
pmic 4:52d2d31a7347 636
pmic 4:52d2d31a7347 637 if (t2 < 0.0f) {
pmic 4:52d2d31a7347 638 float minVelocity = -sqrt((-2.0f*static_cast<float>(targetPosition-position)*profileAcceleration+velocity*velocity)*profileDeceleration/(profileAcceleration+profileDeceleration));
pmic 3:e6d345973797 639 t1 = (velocity-minVelocity)/profileAcceleration;
pmic 3:e6d345973797 640 t2 = 0.0f;
pmic 3:e6d345973797 641 t3 = -minVelocity/profileDeceleration;
pmic 4:52d2d31a7347 642 }
pmic 4:52d2d31a7347 643
pmic 4:52d2d31a7347 644 if (t1 > period) {
pmic 4:52d2d31a7347 645 position += static_cast<double>((velocity-profileAcceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 646 velocity += -profileAcceleration*period;
pmic 4:52d2d31a7347 647 acceleration = -profileAcceleration;
pmic 4:52d2d31a7347 648 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 649 position += static_cast<double>((velocity-profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 650 velocity += -profileAcceleration*t1;
pmic 4:52d2d31a7347 651 position += static_cast<double>(velocity*(period-t1));
pmic 4:52d2d31a7347 652 acceleration = 0.0f;
pmic 4:52d2d31a7347 653 } else if (t1+t2+t3 > period) {
pmic 4:52d2d31a7347 654 position += static_cast<double>((velocity-profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 655 velocity += -profileAcceleration*t1;
pmic 4:52d2d31a7347 656 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 657 position += static_cast<double>((velocity+profileDeceleration*0.5f*(period-t1-t2))*(period-t1-t2));
pmic 4:52d2d31a7347 658 velocity += profileDeceleration*(period-t1-t2);
pmic 4:52d2d31a7347 659 acceleration = profileDeceleration;
pmic 4:52d2d31a7347 660 } else {
pmic 4:52d2d31a7347 661 position += static_cast<double>((velocity-profileAcceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 662 velocity += -profileAcceleration*t1;
pmic 4:52d2d31a7347 663 position += static_cast<double>(velocity*t2);
pmic 4:52d2d31a7347 664 position += static_cast<double>((velocity+profileDeceleration*0.5f*t3)*t3);
pmic 4:52d2d31a7347 665 velocity += profileDeceleration*t3;
pmic 4:52d2d31a7347 666 acceleration = 0.0f;
pmic 4:52d2d31a7347 667 }
pmic 4:52d2d31a7347 668
pmic 4:52d2d31a7347 669 } else { // slow down to zero first, and then speed up to (negative) profile velocity
pmic 4:52d2d31a7347 670
pmic 4:52d2d31a7347 671 float t1 = velocity/profileDeceleration;
pmic 4:52d2d31a7347 672 float t2 = profileVelocity/profileAcceleration;
pmic 4:52d2d31a7347 673 float t4 = profileVelocity/profileDeceleration;
pmic 4:52d2d31a7347 674 float t3 = (-static_cast<float>(targetPosition-position)+velocity*0.5f*t1)/profileVelocity-0.5f*(t2+t4);
pmic 4:52d2d31a7347 675
pmic 4:52d2d31a7347 676 if (t3 < 0.0f) {
pmic 4:52d2d31a7347 677 float minVelocity = -sqrt((-2.0f*static_cast<float>(targetPosition-position)*profileDeceleration+velocity*velocity)*profileAcceleration/(profileAcceleration+profileDeceleration));
pmic 3:e6d345973797 678 t2 = -minVelocity/profileAcceleration;
pmic 3:e6d345973797 679 t3 = 0.0f;
pmic 3:e6d345973797 680 t4 = -minVelocity/profileDeceleration;
pmic 4:52d2d31a7347 681 }
pmic 4:52d2d31a7347 682
pmic 4:52d2d31a7347 683 if (t1 > period) {
pmic 4:52d2d31a7347 684 position += static_cast<double>((velocity-profileDeceleration*0.5f*period)*period);
pmic 4:52d2d31a7347 685 velocity += -profileDeceleration*period;
pmic 4:52d2d31a7347 686 acceleration = -profileDeceleration;
pmic 4:52d2d31a7347 687 } else if (t1+t2 > period) {
pmic 4:52d2d31a7347 688 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 689 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 690 position += static_cast<double>((velocity-profileAcceleration*0.5f*(period-t1))*(period-t1));
pmic 4:52d2d31a7347 691 velocity += -profileAcceleration*(period-t1);
pmic 4:52d2d31a7347 692 acceleration = -profileAcceleration;
pmic 4:52d2d31a7347 693 } else if (t1+t2+t3 > period) {
pmic 4:52d2d31a7347 694 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 695 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 696 position += static_cast<double>((velocity-profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 697 velocity += -profileAcceleration*t2;
pmic 4:52d2d31a7347 698 position += static_cast<double>(velocity*(period-t1-t2));
pmic 4:52d2d31a7347 699 acceleration = 0.0f;
pmic 4:52d2d31a7347 700 } else if (t1+t2+t3+t4 > period) {
pmic 4:52d2d31a7347 701 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 702 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 703 position += static_cast<double>((velocity-profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 704 velocity += -profileAcceleration*t2;
pmic 4:52d2d31a7347 705 position += static_cast<double>(velocity*t3);
pmic 4:52d2d31a7347 706 position += static_cast<double>((velocity+profileDeceleration*0.5f*(period-t1-t2-t3))*(period-t1-t2-t3));
pmic 4:52d2d31a7347 707 velocity += profileDeceleration*(period-t1-t2-t3);
pmic 4:52d2d31a7347 708 acceleration = profileDeceleration;
pmic 4:52d2d31a7347 709 } else {
pmic 4:52d2d31a7347 710 position += static_cast<double>((velocity-profileDeceleration*0.5f*t1)*t1);
pmic 4:52d2d31a7347 711 velocity += -profileDeceleration*t1;
pmic 4:52d2d31a7347 712 position += static_cast<double>((velocity-profileAcceleration*0.5f*t2)*t2);
pmic 4:52d2d31a7347 713 velocity += -profileAcceleration*t2;
pmic 4:52d2d31a7347 714 position += static_cast<double>(velocity*t3);
pmic 4:52d2d31a7347 715 position += static_cast<double>((velocity+profileDeceleration*0.5f*t4)*t4);
pmic 4:52d2d31a7347 716 velocity += profileDeceleration*t4;
pmic 4:52d2d31a7347 717 acceleration = 0.0f;
pmic 4:52d2d31a7347 718 }
pmic 3:e6d345973797 719 }
pmic 3:e6d345973797 720 }
pmic 3:e6d345973797 721 }