JointLimitMonitor.cpp
Go to the documentation of this file.
1 /****************************************************************
2  *
3  * Copyright (c) 2011
4  * All rights reserved.
5  *
6  * Hochschule Bonn-Rhein-Sieg
7  * University of Applied Sciences
8  * Computer Science Department
9  *
10  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11  *
12  * Author:
13  * Jan Paulus, Nico Hochgeschwender, Michael Reckhaus, Azamat Shakhimardanov
14  * Supervised by:
15  * Gerhard K. Kraetzschmar
16  *
17  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18  *
19  * This sofware is published under a dual-license: GNU Lesser General Public
20  * License LGPL 2.1 and BSD license. The dual-license implies that users of this
21  * code may choose which terms they prefer.
22  *
23  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions are met:
27  *
28  * * Redistributions of source code must retain the above copyright
29  * notice, this list of conditions and the following disclaimer.
30  * * Redistributions in binary form must reproduce the above copyright
31  * notice, this list of conditions and the following disclaimer in the
32  * documentation and/or other materials provided with the distribution.
33  * * Neither the name of the Hochschule Bonn-Rhein-Sieg nor the names of its
34  * contributors may be used to endorse or promote products derived from
35  * this software without specific prior written permission.
36  *
37  * This program is free software: you can redistribute it and/or modify
38  * it under the terms of the GNU Lesser General Public License LGPL as
39  * published by the Free Software Foundation, either version 2.1 of the
40  * License, or (at your option) any later version or the BSD license.
41  *
42  * This program is distributed in the hope that it will be useful,
43  * but WITHOUT ANY WARRANTY; without even the implied warranty of
44  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45  * GNU Lesser General Public License LGPL and the BSD license for more details.
46  *
47  * You should have received a copy of the GNU Lesser General Public
48  * License LGPL and BSD license along with this program.
49  *
50  ****************************************************************/
52 namespace youbot {
53 
54 JointLimitMonitor::JointLimitMonitor(const YouBotJointStorage& jointParameters, const quantity<angular_acceleration>& jointAcceleration) {
55  // Bouml preserved body begin 000FAB71
56  this->storage = jointParameters;
57  this->acceleration = jointAcceleration.value(); // rad/s^2
58  brakingDistance = 0;
59  isbraking = false;
61 
62 
63 
64  // Bouml preserved body end 000FAB71
65 }
66 
68  // Bouml preserved body begin 000FABF1
69  // Bouml preserved body end 000FABF1
70 }
71 
73  // Bouml preserved body begin 000FAC71
74  this->storage = source.storage;
75  // Bouml preserved body end 000FAC71
76 }
77 
79  // Bouml preserved body begin 000FACF1
80  this->storage = source.storage;
81  return *this;
82  // Bouml preserved body end 000FACF1
83 }
84 
85 void JointLimitMonitor::checkLimitsPositionControl(const quantity<plane_angle>& setpoint) {
86  // Bouml preserved body begin 000FAD71
87  if (storage.gearRatio == 0) {
88  throw std::out_of_range("A Gear Ratio of zero is not allowed");
89  }
90 
91  if (storage.encoderTicksPerRound == 0) {
92  throw std::out_of_range("Zero Encoder Ticks per Round are not allowed");
93  }
95 
96  quantity<plane_angle> lowLimit = ((double) this->storage.lowerLimit / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
97  quantity<plane_angle> upLimit = ((double) this->storage.upperLimit / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
98 
100  upLimit = ((double) -(this->storage.lowerLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
101  lowLimit = ((double) -(this->storage.upperLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI) * radian;
102  }
103 
104 
105  if (!((setpoint < upLimit) && (setpoint > lowLimit))) {
106  std::stringstream errorMessageStream;
107  errorMessageStream << "The setpoint angle for joint "<< this->storage.jointName << " is out of range. The valid range is between " << lowLimit.value() << " and " << upLimit.value() << " and it is: " << setpoint.value();
108  throw std::out_of_range(errorMessageStream.str());
109  }
110  }
111  // Bouml preserved body end 000FAD71
112 }
113 
114 void JointLimitMonitor::checkLimitsEncoderPosition(const signed int& setpoint) {
115  // Bouml preserved body begin 000FAF71
117  long upLimit = storage.upperLimit;
118  long lowLimit = storage.lowerLimit;
120  upLimit = -storage.lowerLimit;
121  lowLimit = -storage.upperLimit;
122  }
123 
124  if (!((setpoint < upLimit) && (setpoint > lowLimit))) {
125  std::stringstream errorMessageStream;
126  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;
127  throw std::out_of_range(errorMessageStream.str());
128  }
129  }
130  // Bouml preserved body end 000FAF71
131 }
132 
134  // Bouml preserved body begin 000FCAF1
135  switch (messageOutput.controllerMode) {
136  case POSITION_CONTROL:
137  break;
138  case VELOCITY_CONTROL:
139  if (isbraking == false) {
140  calculateBrakingDistance(messageInput);
141  }
142 
143  if ((messageInput.actualPosition < bevorLowerLimit && !(messageOutput.value > 0)) || (messageInput.actualPosition > bevorUpperLimit && !(messageOutput.value < 0))) {
144  // messageOutput.value = velocityWhenReachedLimit * this->calculateDamping(messageInput.actualPosition);
145  messageOutput.value = this->calculateBrakingVelocity(messageInput.actualPosition);
146  isbraking = true;
147  } else {
148  isbraking = false;
149  }
150 
151  break;
152  case CURRENT_MODE:
153  break; //disable limit checker for current mode
154  /*
155  if(isbraking == false){
156  calculateBrakingDistance(messageInput);
157  }
158 
159  if( (messageInput.actualPosition < bevorLowerLimit && !(messageOutput.value > 0)) || (messageInput.actualPosition > bevorUpperLimit && !(messageOutput.value < 0))) {
160  messageOutput.value = this->calculateBrakingVelocity(messageInput.actualPosition);
161  messageOutput.controllerMode = VELOCITY_CONTROL;
162  isbraking = true;
163  }else{
164  isbraking = false;
165  }
166 
167  break;
168  */
169  default:
170 
171  break;
172 
173  }
174 
175  // Bouml preserved body end 000FCAF1
176 }
177 
178 double JointLimitMonitor::calculateDamping(const int actualPosition) {
179  // Bouml preserved body begin 000FAFF1
180  if(actualPosition <= storage.lowerLimit){
181  return 0.0;
182  }
183  if(actualPosition >= storage.upperLimit){
184  return 0.0;
185  }
186  if(actualPosition < bevorLowerLimit){
187  return abs(((double)(actualPosition - storage.lowerLimit))/(bevorLowerLimit - storage.lowerLimit));
188  }
189  if(actualPosition > bevorUpperLimit){
190  return abs(((double)(storage.upperLimit - actualPosition))/(storage.upperLimit - bevorUpperLimit));
191  }
192  return 0.0;
193 
194  // Bouml preserved body end 000FAFF1
195 }
196 
198  // Bouml preserved body begin 000FE471
199  actualVelocityRPS = (((double) messageInput.actualVelocity / 60.0) * storage.gearRatio * 2.0 * M_PI); // radian_per_second;
200 
201  brakingDistance = (int) abs((((actualVelocityRPS * actualVelocityRPS) / (2.0 * acceleration)) * ((double) storage.encoderTicksPerRound / (2.0 * M_PI))) / storage.gearRatio);
202 
206  // Bouml preserved body end 000FE471
207 }
208 
209 int JointLimitMonitor::calculateBrakingVelocity(const int actualPosition) {
210  // Bouml preserved body begin 000FE4F1
211  if(actualPosition <= storage.lowerLimit){
212  return 0;
213  }
214  if(actualPosition >= storage.upperLimit){
215  return 0;
216  }
217  if(actualPosition < bevorLowerLimit){
218  distanceToLimit = ((double) (actualPosition - storage.lowerLimit) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI);
220  return (int) boost::math::round((newVelocity / (storage.gearRatio * 2.0 * M_PI)) * 60.0);
221  }
222  if(actualPosition > bevorUpperLimit){
223  distanceToLimit = ((double) (storage.upperLimit - actualPosition) / storage.encoderTicksPerRound) * storage.gearRatio * (2.0 * M_PI);
225  return (int) boost::math::round((newVelocity / (storage.gearRatio * 2.0 * M_PI)) * 60.0);
226  }
227  return 0;
228 
229  // Bouml preserved body end 000FE4F1
230 }
231 
232 
233 } // namespace youbot
Output part from the EtherCat message of the youBot EtherCat slaves.
JointLimitMonitor(const YouBotJointStorage &jointParameters, const quantity< angular_acceleration > &jointAcceleration)
int calculateBrakingVelocity(const int actualPosition)
void checkLimitsEncoderPosition(const signed int &setpoint)
It monitors the joint position and will decelerate and stop the joint if it is close the limits...
void calculateBrakingDistance(const SlaveMessageInput &messageInput)
void checkLimitsProcessData(const SlaveMessageInput &messageInput, SlaveMessageOutput &messageOutput)
void checkLimitsPositionControl(const quantity< plane_angle > &setpoint)
Input part from the EtherCat message of the youBot EtherCat slaves.
double calculateDamping(const int actualPosition)
JointLimitMonitor & operator=(const JointLimitMonitor &source)
Stores YouBotJoint informations which are needed in the driver.


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Jun 10 2019 15:46:24