VelocityManipulatingTorque.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2017, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarX
19  * @author Mirko Waechter( mirko.waechter at kit dot edu)
20  * @date 2018
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 
27 
29 
31 
33 {
34 
37  pid(torqueConfigData->pid_proportional_gain,
38  torqueConfigData->pid_integral_gain,
39  torqueConfigData->pid_derivative_gain),
40  pidTargetTorque(0, 1, 0),
41  torqueGaussianFilter(30, 30),
42  torqueMedianFilter(5),
43  actualVelocityFilter(5),
46  {
47 
48 
49  pid.threadSafe = false;
50  pid.setMaxControlValue(torqueConfigData->pid_max_value);
51  }
52 
56  bool limitless,
57  float jointLimitLow,
58  float jointLimitHigh)
59  {
61  configData.pid_proportional_gain = config.getFloat("pid_proportional_gain");
62  configData.pid_integral_gain = config.getFloat("pid_integral_gain");
63  configData.pid_derivative_gain = config.getFloat("pid_derivative_gain");
64  configData.pid_max_value = config.getFloat("pid_max_value");
65  configData.accelerationGain = config.getFloat("accelerationGain");
66  configData.deadZone = config.getFloat("deadZone");
67  configData.decay = config.getFloat("decay");
68  configData.maxVelocity = config.getFloat("maxVelocity");
69  configData.maxAcceleration = config.getFloat("maxAcceleration");
70  configData.torqueToCurrent = config.getFloat("torqueToCurrent");
71  configData.maxTargetTorque = config.getFloat("maxTargetTorque");
72 
73  auto v = config.getFloatList("firFilterImpulseResponse");
74  for (auto& elem : v)
75  {
76  configData.firFilterImpulseResponse.push_back(elem);
77  }
78 
79  configData.limitless = limitless;
80  configData.jointLimitLow = jointLimitLow;
81  configData.jointLimitHigh = jointLimitHigh;
82 
83  return std::make_shared<VelocityManipulatingTorqueControllerConfiguration>(configData);
84  }
85 
88  {
89  }
90 
91  double
93  {
94  double jointLimitProtection = 0;
95  if (!torqueConfigData->limitless)
96  {
97  double borderHigh = torqueConfigData->jointLimitHigh - torqueConfigData->pushbackMargin;
98  double borderLow = torqueConfigData->jointLimitLow + torqueConfigData->pushbackMargin;
99  double penetration = 0;
100  if (actualPosition > borderHigh)
101  {
102  penetration = actualPosition - borderHigh;
103  }
104  else if (actualPosition < borderLow)
105  {
106  penetration = actualPosition - borderLow;
107  }
108  jointLimitProtection =
109  penetration / torqueConfigData->pushbackMargin * torqueConfigData->pushBackTorque;
110  }
111  jointLimitProtection =
112  math::MathUtils::LimitTo(jointLimitProtection, torqueConfigData->pushBackTorque);
113  return jointLimitProtection;
114  }
115 
116  double
118  {
119  return lastJerk;
120  }
121 
122  double
124  {
125  return lastAcceleration;
126  }
127 
128  float
130  const IceUtil::Time& timeSinceLastIteration,
131  float gravity,
132  float actualTorque,
133  float targetTorque,
134  float actualVelocity,
135  float actualPosition)
136  {
137  ARMARX_CHECK_EXPRESSION(torqueConfigData);
138  // pidParameterMutex.lock();
139  pid.Kp = torqueConfigData->pid_proportional_gain;
140  pid.Ki = torqueConfigData->pid_integral_gain;
141  pid.Kd = torqueConfigData->pid_derivative_gain;
142 
143  pid.maxDerivation = 30; // avoids rapid oscillation of pid controller
144  pid.setMaxControlValue(torqueConfigData->pid_max_value);
145  // ARMARX_INFO << "PID max value: " << torqueConfigData->pid_max_value;
146 
147  targetTorque = math::MathUtils::LimitTo(targetTorque, torqueConfigData->maxTargetTorque);
148  double decay = torqueConfigData->decay;
149  double accelerationGain = torqueConfigData->accelerationGain;
150  double maxAcceleration = torqueConfigData->maxAcceleration;
151  double maxJerk = torqueConfigData->maxJerk;
152  double deadZone = torqueConfigData->deadZone;
153  double maxVelocity = torqueConfigData->maxVelocity;
154  double torqueToCurrentFactor = torqueConfigData->torqueToCurrent;
155  // pidParameterMutex.unlock();
156 
157 
158  double dt = timeSinceLastIteration.toSecondsDouble(); // sampling time of torque values
159  // double actualTorqueF = filter.update(actualTorque);
160  // actualTorque = torqueMedianFilter.update(actualTorque);
161  actualVelocity = actualVelocityFilter.update(actualVelocity);
162  double gravityCompensatedTorque = -gravity + actualTorque;
163 
164  // apply a deadzone due to model/sensor error
165  // if (std::abs(targetTorque) < 0.1)
166  {
167  gravityCompensatedTorque =
168  math::MathUtils::Sign(gravityCompensatedTorque) *
169  std::max<float>(0.0f, (std::abs(gravityCompensatedTorque) - deadZone));
170  }
171 
172 
173  double jointLimitProtectionTorque = calcJointLimitProtectionTorque(actualPosition);
174  if (std::abs(jointLimitProtectionTorque) > 0.0)
175  {
176  pid.integral *= 0.9; // we dont want an high integral if we are out of the joint limits
177  }
178  jointLimitProtectionTorque = math::MathUtils::LimitTo(
179  jointLimitProtectionTorque, std::abs(targetTorque + gravityCompensatedTorque) * 1.00);
180 
181  double acceleration =
182  (targetTorque + gravityCompensatedTorque - jointLimitProtectionTorque) *
183  accelerationGain; // torque is an acceleration
184  acceleration = math::MathUtils::LimitTo(
185  acceleration,
186  maxAcceleration); // joints cannot/should not accelerate faster than this by zero torque control
187 
188  acceleration = math::MathUtils::LimitMinMax(
189  lastAcceleration - maxJerk * dt, lastAcceleration + maxJerk * dt, acceleration);
190  if (math::MathUtils::Sign(currentTargetVelocity) == math::MathUtils::Sign(acceleration))
191  {
192  decay /= std::max(
193  std::abs(gravityCompensatedTorque),
194  1.0); // less decay when external torque is applied for easier zero torque control
195  }
196  currentTargetVelocity += acceleration * dt;
197  lastJerk = (acceleration - lastAcceleration) / dt;
198  lastAcceleration = acceleration;
199 
201  1.0,
202  15.0,
203  std::abs(
204  gravityCompensatedTorque *
205  gravityCompensatedTorque)); // if external torque is applied, the decay is reduced to have a lighter torque control
206 
207  decay = math::MathUtils::LimitMinMax(0.0, 1.0, decay);
208  currentTargetVelocity *=
209  1.0 - decay; // damping - slows down joint motion (important if no torque is applied)
210  currentTargetVelocity = math::MathUtils::LimitTo(
211  currentTargetVelocity,
212  maxVelocity); // some joints should not be moved over a certain velocity
213  pid.update(dt, actualVelocity, currentTargetVelocity);
214  double resultingTargetCurrent = -pid.getControlValue() * 1000.0;
215 
216 
217  double directControlCurrent = 0.; //gravity * torqueToCurrentFactor * 1000;
218 
219  // ARMARX_RT_LOGF_INFO("direct-control: %.3f, currentTargetVelocity: %.3f, current Vel: %.3f, g-torque: %.2f, actual torque: %.2f, "
220  // "torqueDiff: %.3f, target torque: %.2f, acc: %.3f, target current: %.3f, Kp: %.1f, Ki: %.1f, cur Integral: %.4f, "
221  // "Kd: %0.2f, pid MaxVal: %.2f, a-gain: %.2f, current jerk: %.2f, deadZone: %.1f, decay: %.4f"
222  // ,
223  // directControlCurrent, currentTargetVelocity, actualVelocity, gravity, actualTorque,
224  // gravityCompensatedTorque, targetTorque, acceleration,
225  // resultingTargetCurrent, pid.Kp, pid.Ki, pid.integral, pid.Kd, pid.maxControlValue,
226  // accelerationGain, lastJerk, deadZone, decay).deactivateSpam(0.3);
227 
228  // calculate a current that protects the joint limits
229  auto jointLimitProtectionCurrent =
230  calcJointLimitProtectionTorque(actualPosition) *
231  (torqueToCurrentFactor == 0.0 ? 0.05 : torqueToCurrentFactor) * 1000;
232  // ARMARX_RT_LOGF_INFO("targetCurrent: %.3f, protection torque: %.3f",
233  // resultingTargetCurrent, jointLimitProtectionTorque).deactivateSpam(0.3);
234  return resultingTargetCurrent + directControlCurrent + jointLimitProtectionCurrent;
235  }
236 
237  void
239  {
240  pid.reset();
241  currentTargetVelocity = 0.0;
242  lastAcceleration = 0.0;
243  lastJerk = 0.0;
244  }
245 
246  double
248  {
249  return currentTargetVelocity;
250  }
251 
254  {
255  return *torqueConfigData;
256  }
257 
258  bool
261  {
262  // if (pidParameterMutex.try_lock())
263  // {
264  torqueConfigData->pid_proportional_gain = configData.pid_proportional_gain;
265  torqueConfigData->pid_integral_gain = configData.pid_integral_gain;
266  torqueConfigData->pid_derivative_gain = configData.pid_derivative_gain;
267 
268  torqueConfigData->decay = configData.decay;
269  torqueConfigData->deadZone = configData.deadZone;
270 
271  // ARMARX_INFO << "Updated control parameters";
272 
273 
274  // }
275 
276  return true;
277  }
278 
279  const PIDController&
281  {
282  return pid;
283  }
284 
285 } // namespace armarx::control::joint_controller
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::VelocityManipulatingTorqueControllerConfiguration
VelocityManipulatingTorqueControllerConfiguration()
Definition: VelocityManipulatingTorque.cpp:87
armarx::PIDController::Kp
float Kp
Definition: PIDController.h:68
armarx::control::hardware_config::Config::getFloatList
std::list< float > getFloatList(const std::string name)
Get a FloatList (std::list<float>) typed Config attribute by name.
Definition: Config.cpp:58
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::pid_integral_gain
double pid_integral_gain
Definition: VelocityManipulatingTorque.h:57
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::deadZone
double deadZone
Definition: VelocityManipulatingTorque.h:61
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::torqueToCurrent
double torqueToCurrent
Definition: VelocityManipulatingTorque.h:66
armarx::control::joint_controller::VelocityManipulatingTorqueController::getPid
const PIDController & getPid()
Definition: VelocityManipulatingTorque.cpp:280
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration
Definition: VelocityManipulatingTorque.h:47
armarx::PIDController::Ki
float Ki
Definition: PIDController.h:68
armarx::control::joint_controller::VelocityManipulatingTorqueController::reset
void reset()
Definition: VelocityManipulatingTorque.cpp:238
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::decay
double decay
Definition: VelocityManipulatingTorque.h:62
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::accelerationGain
double accelerationGain
Definition: VelocityManipulatingTorque.h:60
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::pid_proportional_gain
double pid_proportional_gain
Definition: VelocityManipulatingTorque.h:56
armarx::control::joint_controller::VelocityManipulatingTorqueController::setTorqueConfigData
bool setTorqueConfigData(VelocityManipulatingTorqueControllerConfiguration configData)
Definition: VelocityManipulatingTorque.cpp:259
armarx::PIDController::Kd
float Kd
Definition: PIDController.h:68
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::firFilterImpulseResponse
std::vector< float > firFilterImpulseResponse
Definition: VelocityManipulatingTorque.h:72
armarx::PIDController::getControlValue
double getControlValue() const
Definition: PIDController.cpp:273
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::maxTargetTorque
double maxTargetTorque
Definition: VelocityManipulatingTorque.h:67
armarx::PIDController::update
void update(double deltaSec, double measuredValue, double targetValue)
Definition: PIDController.cpp:211
armarx::control::joint_controller::VelocityManipulatingTorqueController::getTorqueConfigData
VelocityManipulatingTorqueControllerConfiguration getTorqueConfigData() const
Definition: VelocityManipulatingTorque.cpp:253
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::jointLimitLow
double jointLimitLow
Definition: VelocityManipulatingTorque.h:69
armarx::control::joint_controller::VelocityManipulatingTorqueController::calcJointLimitProtectionTorque
double calcJointLimitProtectionTorque(float actualPosition)
Definition: VelocityManipulatingTorque.cpp:92
armarx::PIDController::reset
void reset()
Definition: PIDController.cpp:148
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:253
armarx::control::joint_controller::VelocityManipulatingTorqueController::VelocityManipulatingTorqueController
VelocityManipulatingTorqueController(const VelocityManipulatingTorqueControllerConfigurationPtr &torqueConfigData)
Definition: VelocityManipulatingTorque.cpp:35
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::jointLimitHigh
double jointLimitHigh
Definition: VelocityManipulatingTorque.h:69
armarx::PIDController
Definition: PIDController.h:43
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfigurationPtr
std::shared_ptr< class VelocityManipulatingTorqueControllerConfiguration > VelocityManipulatingTorqueControllerConfigurationPtr
Definition: VelocityManipulatingTorque.h:45
VelocityManipulatingTorque.h
max
T max(T t1, T t2)
Definition: gdiam.h:48
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::pid_max_value
double pid_max_value
Definition: VelocityManipulatingTorque.h:59
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::control::joint_controller::VelocityManipulatingTorqueController::getCurrentTargetVelocity
double getCurrentTargetVelocity() const
Definition: VelocityManipulatingTorque.cpp:247
armarx::PIDController::threadSafe
bool threadSafe
Definition: PIDController.h:83
armarx::PIDController::integral
double integral
Definition: PIDController.h:69
armarx::control::joint_controller::VelocityManipulatingTorqueController::update
float update(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration, float gravity, float actualTorque, float targetTorque, float actualVelocity, float actualPosition)
Definition: VelocityManipulatingTorque.cpp:129
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::math::MathUtils::LimitTo
static double LimitTo(double value, double absThreshold)
Definition: MathUtils.h:56
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::CreateTorqueConfigData
static VelocityManipulatingTorqueControllerConfigurationPtr CreateTorqueConfigData(hardware_config::Config &config, bool limitless, float jointLimitLow, float jointLimitHigh)
Definition: VelocityManipulatingTorque.cpp:54
armarx::math::MathUtils::LimitMinMax
static int LimitMinMax(int min, int max, int value)
Definition: MathUtils.h:39
armarx::control::joint_controller
Definition: ControllerConfiguration.cpp:3
armarx::math::MathUtils::Sign
static int Sign(double value)
Definition: MathUtils.h:34
armarx::control::hardware_config::Config
The Config class is the base class of all specialized configurations that have a direct key -> value ...
Definition: Config.h:91
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::maxVelocity
double maxVelocity
Definition: VelocityManipulatingTorque.h:63
ControlThreadOutputBuffer.h
Logging.h
armarx::control::joint_controller::VelocityManipulatingTorqueController::getLastJerk
double getLastJerk() const
Definition: VelocityManipulatingTorque.cpp:117
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::limitless
bool limitless
Definition: VelocityManipulatingTorque.h:68
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::maxAcceleration
double maxAcceleration
Definition: VelocityManipulatingTorque.h:64
armarx::PIDController::maxDerivation
double maxDerivation
Definition: PIDController.h:80
armarx::control::hardware_config::Config::getFloat
float getFloat(const std::string name)
Get a Float typed Config attribute by name.
Definition: Config.cpp:16
armarx::control::joint_controller::VelocityManipulatingTorqueController::getLastAcceleration
double getLastAcceleration() const
Definition: VelocityManipulatingTorque.cpp:123
armarx::control::joint_controller::VelocityManipulatingTorqueControllerConfiguration::pid_derivative_gain
double pid_derivative_gain
Definition: VelocityManipulatingTorque.h:58
dt
constexpr T dt
Definition: UnscentedKalmanFilterTest.cpp:42
armarx::control::rt_filters::RtMedianFilter::update
float update(float value)
Definition: RtMedianFilter.cpp:15
armarx::PIDController::setMaxControlValue
void setMaxControlValue(double newMax)
Definition: PIDController.cpp:205