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/JointLimitMonitor.hpp"
00052 namespace youbot {
00053 
00054 JointLimitMonitor::JointLimitMonitor(const YouBotJointStorage& jointParameters, const quantity<angular_acceleration>& jointAcceleration) {
00055   // Bouml preserved body begin 000FAB71
00056   this->storage = jointParameters;
00057   this->acceleration = jointAcceleration.value();  // rad/s^2
00058   brakingDistance = 0;
00059   isbraking = false;
00060   velocityWhenReachedLimit = 0;
00061           
00062 
00063 
00064   // Bouml preserved body end 000FAB71
00065 }
00066 
00067 JointLimitMonitor::~JointLimitMonitor() {
00068   // Bouml preserved body begin 000FABF1
00069   // Bouml preserved body end 000FABF1
00070 }
00071 
00072 JointLimitMonitor::JointLimitMonitor(const JointLimitMonitor & source) {
00073   // Bouml preserved body begin 000FAC71
00074   this->storage = source.storage;
00075   // Bouml preserved body end 000FAC71
00076 }
00077 
00078 JointLimitMonitor & JointLimitMonitor::operator=(const JointLimitMonitor & source) {
00079   // Bouml preserved body begin 000FACF1
00080   this->storage = source.storage;
00081   return *this;
00082   // Bouml preserved body end 000FACF1
00083 }
00084 
00085 void JointLimitMonitor::checkLimitsPositionControl(const quantity<plane_angle>& setpoint) {
00086   // Bouml preserved body begin 000FAD71
00087   if (storage.gearRatio == 0) {
00088       throw std::out_of_range("A Gear Ratio of zero is not allowed");
00089     }
00090     
00091     if (storage.encoderTicksPerRound == 0) {
00092       throw std::out_of_range("Zero Encoder Ticks per Round are not allowed");
00093     }
00094     if(storage.areLimitsActive){
00095 
00096       quantity<plane_angle> lowLimit = ((double) this->storage.lowerLimit / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
00097       quantity<plane_angle> upLimit = ((double) this->storage.upperLimit / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
00098       
00099       if (storage.inverseMovementDirection) {
00100         upLimit = ((double) -(this->storage.lowerLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
00101         lowLimit = ((double) -(this->storage.upperLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
00102       }
00103       
00104 
00105       if (!((setpoint < upLimit) && (setpoint > lowLimit))) {
00106         std::stringstream errorMessageStream;
00107         errorMessageStream << "The setpoint angle for joint "<< this->storage.jointName <<" is out of range. The valid range is between " << lowLimit << " and " << upLimit << " and it is: " << setpoint;
00108         throw std::out_of_range(errorMessageStream.str());
00109       }
00110     }
00111   // Bouml preserved body end 000FAD71
00112 }
00113 
00114 void JointLimitMonitor::checkLimitsEncoderPosition(const signed int& setpoint) {
00115   // Bouml preserved body begin 000FAF71
00116   if(storage.areLimitsActive){
00117       if (!((setpoint < this->storage.upperLimit) && (setpoint > this->storage.lowerLimit))) {
00118         std::stringstream errorMessageStream;
00119         errorMessageStream << "The setpoint angle for joint "<< this->storage.jointName <<" is out of range. The valid range is between " << this->storage.lowerLimit << " and " << this->storage.upperLimit << " and it is: " << setpoint;
00120         throw std::out_of_range(errorMessageStream.str());
00121       }
00122     }
00123   // Bouml preserved body end 000FAF71
00124 }
00125 
00126 void JointLimitMonitor::checkLimitsProcessData(const SlaveMessageInput& messageInput, SlaveMessageOutput& messageOutput) {
00127   // Bouml preserved body begin 000FCAF1
00128     switch (messageOutput.controllerMode) {
00129       case POSITION_CONTROL:
00130         break;
00131       case VELOCITY_CONTROL:
00132         if (isbraking == false) {
00133           calculateBrakingDistance(messageInput);
00134         }
00135 
00136         if ((messageInput.actualPosition < bevorLowerLimit && !(messageOutput.value > 0)) || (messageInput.actualPosition > bevorUpperLimit && !(messageOutput.value < 0))) {
00137           //  messageOutput.value = velocityWhenReachedLimit * this->calculateDamping(messageInput.actualPosition);
00138           messageOutput.value = this->calculateBrakingVelocity(messageInput.actualPosition);
00139           isbraking = true;
00140         } else {
00141           isbraking = false;
00142         }
00143 
00144         break;
00145       case CURRENT_MODE:
00146         break; //disable limit checker for current mode
00147         /*
00148         if(isbraking == false){
00149           calculateBrakingDistance(messageInput);
00150         }
00151           
00152         if( (messageInput.actualPosition < bevorLowerLimit && !(messageOutput.value > 0)) || (messageInput.actualPosition > bevorUpperLimit && !(messageOutput.value < 0))) {
00153           messageOutput.value = this->calculateBrakingVelocity(messageInput.actualPosition);
00154           messageOutput.controllerMode = VELOCITY_CONTROL;
00155           isbraking = true;
00156         }else{
00157           isbraking = false;
00158         }
00159 
00160         break;
00161          */
00162       default:
00163 
00164         break;
00165 
00166     }
00167     
00168   // Bouml preserved body end 000FCAF1
00169 }
00170 
00171 double JointLimitMonitor::calculateDamping(const int actualPosition) {
00172   // Bouml preserved body begin 000FAFF1
00173   if(actualPosition <= storage.lowerLimit){
00174     return 0.0;
00175   }
00176   if(actualPosition >= storage.upperLimit){
00177     return 0.0;
00178   }
00179   if(actualPosition < bevorLowerLimit){
00180     return abs(((double)(actualPosition - storage.lowerLimit))/(bevorLowerLimit - storage.lowerLimit));
00181   }
00182   if(actualPosition > bevorUpperLimit){
00183     return abs(((double)(storage.upperLimit - actualPosition))/(storage.upperLimit - bevorUpperLimit));
00184   }
00185   return 0.0;
00186   
00187   // Bouml preserved body end 000FAFF1
00188 }
00189 
00190 void JointLimitMonitor::calculateBrakingDistance(const SlaveMessageInput& messageInput) {
00191   // Bouml preserved body begin 000FE471
00192     actualVelocityRPS = (((double) messageInput.actualVelocity / 60.0) * storage.gearRatio * 2.0 * M_PI); // radian_per_second;
00193 
00194     brakingDistance = abs((((actualVelocityRPS * actualVelocityRPS) / (2.0 * acceleration)) * ((double) storage.encoderTicksPerRound / (2.0 * M_PI))) / storage.gearRatio);
00195 
00196     bevorLowerLimit = storage.lowerLimit + brakingDistance;
00197     bevorUpperLimit = storage.upperLimit - brakingDistance;
00198     velocityWhenReachedLimit = messageInput.actualVelocity;
00199   // Bouml preserved body end 000FE471
00200 }
00201 
00202 int JointLimitMonitor::calculateBrakingVelocity(const int actualPosition) {
00203   // Bouml preserved body begin 000FE4F1
00204   if(actualPosition <= storage.lowerLimit){
00205     return 0;
00206   }
00207   if(actualPosition >= storage.upperLimit){
00208     return 0;
00209   }
00210   if(actualPosition < bevorLowerLimit){
00211     distanceToLimit = ((double) (actualPosition - storage.lowerLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI);
00212     newVelocity =  -sqrt(2.0*acceleration* distanceToLimit);
00213     return round((newVelocity / (storage.gearRatio * 2.0 * M_PI)) * 60.0);
00214   }
00215   if(actualPosition > bevorUpperLimit){
00216     distanceToLimit = ((double) (storage.upperLimit - actualPosition) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI);
00217     newVelocity =  sqrt(2.0*acceleration* distanceToLimit);
00218     return round((newVelocity / (storage.gearRatio * 2.0 * M_PI)) * 60.0);
00219   }
00220   return 0;
00221   
00222   // Bouml preserved body end 000FE4F1
00223 }
00224 
00225 
00226 } // namespace youbot
Generated by  doxygen 1.6.3