JointLimitMonitor.cpp
Go to the documentation of this file.
00001 /****************************************************************
00002  *
00003  * Copyright (c) 2011
00004  * All rights reserved.
00005  *
00006  * Hochschule Bonn-Rhein-Sieg
00007  * University of Applied Sciences
00008  * Computer Science Department
00009  *
00010  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00011  *
00012  * Author:
00013  * Jan Paulus, Nico Hochgeschwender, Michael Reckhaus, Azamat Shakhimardanov
00014  * Supervised by:
00015  * Gerhard K. Kraetzschmar
00016  *
00017  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00018  *
00019  * This sofware is published under a dual-license: GNU Lesser General Public 
00020  * License LGPL 2.1 and BSD license. The dual-license implies that users of this
00021  * code may choose which terms they prefer.
00022  *
00023  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00024  *
00025  * Redistribution and use in source and binary forms, with or without
00026  * modification, are permitted provided that the following conditions are met:
00027  *
00028  *     * Redistributions of source code must retain the above copyright
00029  *       notice, this list of conditions and the following disclaimer.
00030  *     * Redistributions in binary form must reproduce the above copyright
00031  *       notice, this list of conditions and the following disclaimer in the
00032  *       documentation and/or other materials provided with the distribution.
00033  *     * Neither the name of the Hochschule Bonn-Rhein-Sieg nor the names of its
00034  *       contributors may be used to endorse or promote products derived from
00035  *       this software without specific prior written permission.
00036  *
00037  * This program is free software: you can redistribute it and/or modify
00038  * it under the terms of the GNU Lesser General Public License LGPL as
00039  * published by the Free Software Foundation, either version 2.1 of the
00040  * License, or (at your option) any later version or the BSD license.
00041  *
00042  * This program is distributed in the hope that it will be useful,
00043  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00044  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00045  * GNU Lesser General Public License LGPL and the BSD license for more details.
00046  *
00047  * You should have received a copy of the GNU Lesser General Public
00048  * License LGPL and BSD license along with this program.
00049  *
00050  ****************************************************************/
00051 #include <youbot_driver/youbot/JointLimitMonitor.hpp>
00052 namespace youbot
00053 {
00054 
00055 JointLimitMonitor::JointLimitMonitor(const YouBotJointStorage& jointParameters,
00056                                      const quantity<angular_acceleration>& jointAcceleration)
00057 {
00058   // Bouml preserved body begin 000FAB71
00059   this->storage = jointParameters;
00060   this->acceleration = jointAcceleration.value();  // rad/s^2
00061   brakingDistance = 0;
00062   isbraking = false;
00063   velocityWhenReachedLimit = 0;
00064 
00065   // Bouml preserved body end 000FAB71
00066 }
00067 
00068 JointLimitMonitor::~JointLimitMonitor()
00069 {
00070   // Bouml preserved body begin 000FABF1
00071   // Bouml preserved body end 000FABF1
00072 }
00073 
00074 JointLimitMonitor::JointLimitMonitor(const JointLimitMonitor & source)
00075 {
00076   // Bouml preserved body begin 000FAC71
00077   this->storage = source.storage;
00078   // Bouml preserved body end 000FAC71
00079 }
00080 
00081 JointLimitMonitor & JointLimitMonitor::operator=(const JointLimitMonitor & source)
00082 {
00083   // Bouml preserved body begin 000FACF1
00084   this->storage = source.storage;
00085   return *this;
00086   // Bouml preserved body end 000FACF1
00087 }
00088 
00089 void JointLimitMonitor::checkLimitsPositionControl(const quantity<plane_angle>& setpoint)
00090 {
00091   // Bouml preserved body begin 000FAD71
00092   if (storage.gearRatio == 0)
00093   {
00094     throw std::out_of_range("A Gear Ratio of zero is not allowed");
00095   }
00096 
00097   if (storage.encoderTicksPerRound == 0)
00098   {
00099     throw std::out_of_range("Zero Encoder Ticks per Round are not allowed");
00100   }
00101   if (storage.areLimitsActive)
00102   {
00103 
00104     quantity<plane_angle> lowLimit = ((double)this->storage.lowerLimit / storage.encoderTicksPerRound)
00105         * storage.gearRatio * (2.0 * M_PI) * radian;
00106     quantity<plane_angle> upLimit = ((double)this->storage.upperLimit / storage.encoderTicksPerRound)
00107         * storage.gearRatio * (2.0 * M_PI) * radian;
00108 
00109     if (storage.inverseMovementDirection)
00110     {
00111       upLimit = ((double)-(this->storage.lowerLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI)
00112           * radian;
00113       lowLimit = ((double)-(this->storage.upperLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI)
00114           * radian;
00115     }
00116 
00117     if (!((setpoint < upLimit) && (setpoint > lowLimit)))
00118     {
00119       std::stringstream errorMessageStream;
00120       errorMessageStream << "The setpoint angle for joint " << this->storage.jointName
00121           << " is out of range. The valid range is between " << lowLimit << " and " << upLimit << " and it is: "
00122           << setpoint;
00123       throw std::out_of_range(errorMessageStream.str());
00124     }
00125   }
00126   // Bouml preserved body end 000FAD71
00127 }
00128 
00129 void JointLimitMonitor::checkLimitsEncoderPosition(const signed int& setpoint)
00130 {
00131   // Bouml preserved body begin 000FAF71
00132   if (storage.areLimitsActive)
00133   {
00134     if (!((setpoint < this->storage.upperLimit) && (setpoint > this->storage.lowerLimit)))
00135     {
00136       std::stringstream errorMessageStream;
00137       errorMessageStream << "The setpoint angle for joint " << this->storage.jointName
00138           << " is out of range. The valid range is between " << this->storage.lowerLimit << " and "
00139           << this->storage.upperLimit << " and it is: " << setpoint;
00140       throw std::out_of_range(errorMessageStream.str());
00141     }
00142   }
00143   // Bouml preserved body end 000FAF71
00144 }
00145 
00146 void JointLimitMonitor::checkLimitsProcessData(const SlaveMessageInput& messageInput, SlaveMessageOutput& messageOutput)
00147 {
00148   // Bouml preserved body begin 000FCAF1
00149   switch (messageOutput.controllerMode)
00150   {
00151     case POSITION_CONTROL:
00152       break;
00153     case VELOCITY_CONTROL:
00154       if (isbraking == false)
00155       {
00156         calculateBrakingDistance(messageInput);
00157       }
00158 
00159       if ((messageInput.actualPosition < bevorLowerLimit && !(messageOutput.value > 0))
00160           || (messageInput.actualPosition > bevorUpperLimit && !(messageOutput.value < 0)))
00161       {
00162         //      messageOutput.value = velocityWhenReachedLimit * this->calculateDamping(messageInput.actualPosition);
00163         messageOutput.value = this->calculateBrakingVelocity(messageInput.actualPosition);
00164         isbraking = true;
00165       }
00166       else
00167       {
00168         isbraking = false;
00169       }
00170 
00171       break;
00172     case CURRENT_MODE:
00173       break; //disable limit checker for current mode
00174       /*
00175        if(isbraking == false){
00176        calculateBrakingDistance(messageInput);
00177        }
00178 
00179        if( (messageInput.actualPosition < bevorLowerLimit && !(messageOutput.value > 0)) || (messageInput.actualPosition > bevorUpperLimit && !(messageOutput.value < 0))) {
00180        messageOutput.value = this->calculateBrakingVelocity(messageInput.actualPosition);
00181        messageOutput.controllerMode = VELOCITY_CONTROL;
00182        isbraking = true;
00183        }else{
00184        isbraking = false;
00185        }
00186 
00187        break;
00188        */
00189     default:
00190 
00191       break;
00192 
00193   }
00194 
00195   // Bouml preserved body end 000FCAF1
00196 }
00197 
00198 double JointLimitMonitor::calculateDamping(const int actualPosition)
00199 {
00200   // Bouml preserved body begin 000FAFF1
00201   if (actualPosition <= storage.lowerLimit)
00202   {
00203     return 0.0;
00204   }
00205   if (actualPosition >= storage.upperLimit)
00206   {
00207     return 0.0;
00208   }
00209   if (actualPosition < bevorLowerLimit)
00210   {
00211     return abs(((double)(actualPosition - storage.lowerLimit)) / (bevorLowerLimit - storage.lowerLimit));
00212   }
00213   if (actualPosition > bevorUpperLimit)
00214   {
00215     return abs(((double)(storage.upperLimit - actualPosition)) / (storage.upperLimit - bevorUpperLimit));
00216   }
00217   return 0.0;
00218 
00219   // Bouml preserved body end 000FAFF1
00220 }
00221 
00222 void JointLimitMonitor::calculateBrakingDistance(const SlaveMessageInput& messageInput)
00223 {
00224   // Bouml preserved body begin 000FE471
00225   actualVelocityRPS = (((double)messageInput.actualVelocity / 60.0) * storage.gearRatio * 2.0 * M_PI); // radian_per_second;
00226 
00227   brakingDistance = abs(
00228       (((actualVelocityRPS * actualVelocityRPS) / (2.0 * acceleration))
00229           * ((double)storage.encoderTicksPerRound / (2.0 * M_PI))) / storage.gearRatio);
00230 
00231   bevorLowerLimit = storage.lowerLimit + brakingDistance;
00232   bevorUpperLimit = storage.upperLimit - brakingDistance;
00233   velocityWhenReachedLimit = messageInput.actualVelocity;
00234   // Bouml preserved body end 000FE471
00235 }
00236 
00237 int JointLimitMonitor::calculateBrakingVelocity(const int actualPosition)
00238 {
00239   // Bouml preserved body begin 000FE4F1
00240   if (actualPosition <= storage.lowerLimit)
00241   {
00242     return 0;
00243   }
00244   if (actualPosition >= storage.upperLimit)
00245   {
00246     return 0;
00247   }
00248   if (actualPosition < bevorLowerLimit)
00249   {
00250     distanceToLimit = ((double)(actualPosition - storage.lowerLimit) / storage.encoderTicksPerRound) * storage.gearRatio
00251         * (2.0 * M_PI);
00252     newVelocity = -sqrt(2.0 * acceleration * distanceToLimit);
00253     return round((newVelocity / (storage.gearRatio * 2.0 * M_PI)) * 60.0);
00254   }
00255   if (actualPosition > bevorUpperLimit)
00256   {
00257     distanceToLimit = ((double)(storage.upperLimit - actualPosition) / storage.encoderTicksPerRound) * storage.gearRatio
00258         * (2.0 * M_PI);
00259     newVelocity = sqrt(2.0 * acceleration * distanceToLimit);
00260     return round((newVelocity / (storage.gearRatio * 2.0 * M_PI)) * 60.0);
00261   }
00262   return 0;
00263 
00264   // Bouml preserved body end 000FE4F1
00265 }
00266 
00267 } // namespace youbot


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Oct 6 2014 09:08:01