00001 00013 /************************************************************************ 00014 * Copyright (C) 2012 Eindhoven University of Technology (TU/e). * 00015 * All rights reserved. * 00016 ************************************************************************ 00017 * Redistribution and use in source and binary forms, with or without * 00018 * modification, are permitted provided that the following conditions * 00019 * are met: * 00020 * * 00021 * 1. Redistributions of source code must retain the above * 00022 * copyright notice, this list of conditions and the following * 00023 * disclaimer. * 00024 * * 00025 * 2. Redistributions in binary form must reproduce the above * 00026 * copyright notice, this list of conditions and the following * 00027 * disclaimer in the documentation and/or other materials * 00028 * provided with the distribution. * 00029 * * 00030 * THIS SOFTWARE IS PROVIDED BY TU/e "AS IS" AND ANY EXPRESS OR * 00031 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * 00032 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * 00033 * ARE DISCLAIMED. IN NO EVENT SHALL TU/e OR CONTRIBUTORS BE LIABLE * 00034 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * 00035 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * 00036 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * 00037 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * 00038 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 00039 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * 00040 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * 00041 * DAMAGE. * 00042 * * 00043 * The views and conclusions contained in the software and * 00044 * documentation are those of the authors and should not be * 00045 * interpreted as representing official policies, either expressed or * 00046 * implied, of TU/e. * 00047 ************************************************************************/ 00048 00049 #include <ros/ros.h> 00050 #include <amigo_gazebo/ref_generator.h> 00051 00052 using namespace controller; 00053 00054 RefGenerator::RefGenerator(double current_pos, double max_vel, double max_acc) : 00055 pos_(current_pos), vel_(0), acc_(0), max_vel_(max_vel), max_acc_(max_acc) { 00056 } 00057 00058 RefGenerator::~RefGenerator() { 00059 } 00060 00061 int RefGenerator::signum(double a) { 00062 if (a < 0) { 00063 return -1; 00064 } else { 00065 return 1; 00066 } 00067 } 00068 00069 00070 void RefGenerator::setCurrentPosition(double x) { 00071 pos_ = x; 00072 } 00073 00074 void RefGenerator::setCurrentVelocity(double vel) { 00075 vel_ = vel; 00076 } 00077 00078 double RefGenerator::getPositionReference() { 00079 return pos_; 00080 } 00081 00082 double RefGenerator::getVelocityReference() { 00083 return vel_; 00084 } 00085 00086 double RefGenerator::getAccelerationReference() { 00087 return acc_; 00088 } 00089 00090 void RefGenerator::generate(double x_desired, double dt, bool force_stop) { 00091 double dx = x_desired - pos_; 00092 double dx_mag = fabs(dx); 00093 double vel_mag = fabs(vel_); 00094 00095 if (dx_mag < EPSILON && vel_mag < EPSILON) { 00096 // already at correct location with zero velocity, so nothing happens 00097 return; 00098 } 00099 00100 double dir = signum(vel_); 00101 double dir_desired = signum(dx); 00102 00103 if (force_stop || dir != dir_desired) { 00104 // force stopping or going in the wrong direction, so decelerate 00105 acc_ = -max_acc_; 00106 } else { 00107 00108 double dt_dec = vel_mag / max_acc_; //deceleration segment time 00109 double dx_dec = 0.5 * max_acc_ * dt_dec * dt_dec; //deceleration distance 00110 00111 if (dx_mag <= dx_dec) { 00112 // decelerate to prevent overshoot 00113 acc_ = -max_acc_; 00114 } else { 00115 acc_ = max_acc_; 00116 } 00117 } 00118 00119 vel_ = vel_ + acc_ * dir * dt; 00120 if (vel_ < -max_vel_) { 00121 vel_ = -max_vel_; 00122 acc_ = 0; 00123 } else if (vel_ > max_vel_) { 00124 vel_ = max_vel_; 00125 acc_ = 0; 00126 } 00127 00128 pos_ += vel_ * dt; 00129 }