DSRTController.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package DSController::ArmarXObjects::DSRTController
17  * @author Mahdi Khoramshahi ( m80 dot khoramshahi at gmail dot com )
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #ifndef _ARMARX_LIB_DSController_DSRTController_H
24 #define _ARMARX_LIB_DSController_DSRTController_H
25 
26 #include <VirtualRobot/VirtualRobot.h>
27 
29 
34 
35 #include <armarx/control/ds_controller/DSControllerInterface.h>
36 
37 #include "GMRDynamics.h"
38 #include "MathLib.h"
39 
41 {
43  {
44  public:
45  Eigen::Vector3f tcpDesiredLinearVelocity;
46  Eigen::Vector3f tcpDesiredAngularError;
47  };
48 
50  {
51  int K_gmm_;
52  int dim_;
53  std::vector<double> Priors_;
54  std::vector<double> Mu_;
55  std::vector<double> Sigma_;
56  std::vector<double> attractor_;
57  double dt_;
58  };
59 
61  {
62  public:
64  {
65  }
66 
67  GMMMotionGen(const std::string& fileName)
68  {
69  getGMMParamsFromJsonFile(fileName);
70  }
71 
74  Eigen::Vector3f desiredDefaultTarget;
75  float scaling;
76 
77  float belief;
78  float v_max;
79 
80  void
81  getGMMParamsFromJsonFile(const std::string& fileName)
82  {
83  std::ifstream infile{fileName};
84  std::string objDefs = {std::istreambuf_iterator<char>(infile),
85  std::istreambuf_iterator<char>()};
86  JSONObjectPtr json = new JSONObject();
87  json->fromString(objDefs);
88 
89 
90  gmmParas.K_gmm_ = json->getInt("K");
91  gmmParas.dim_ = json->getInt("dim");
92  json->getArray<double>("Priors", gmmParas.Priors_);
93  json->getArray<double>("Mu", gmmParas.Mu_);
94  json->getArray<double>("attractor", gmmParas.attractor_);
95  json->getArray<double>("Sigma", gmmParas.Sigma_);
96 
97  scaling = json->getDouble("Scaling");
98  belief = json->getDouble("InitBelief");
99  belief = 0;
100  v_max = json->getDouble("MaxVelocity");
101 
102  gmm.reset(new GMRDynamics(gmmParas.K_gmm_,
103  gmmParas.dim_,
104  gmmParas.dt_,
106  gmmParas.Mu_,
107  gmmParas.Sigma_));
108  gmm->initGMR(0, 2, 3, 5);
109 
110  if (gmmParas.attractor_.size() < 3)
111  {
112  ARMARX_ERROR << "attractor in json file should be 6 dimension vector ... ";
113  }
114 
115  for (int i = 0; i < 3; ++i)
116  {
118  }
119  }
120 
121  void
122  updateDesiredVelocity(const Eigen::Vector3f& currentPositionInMeter,
123  float positionErrorToleranceInMeter)
124  {
125  Eigen::Vector3f PositionError = currentPositionInMeter - desiredDefaultTarget;
126  if (PositionError.norm() < positionErrorToleranceInMeter)
127  {
128  PositionError.setZero();
129  }
130 
131  MathLib::Vector position_error;
132  position_error.Resize(3);
133 
134  for (int i = 0; i < 3; ++i)
135  {
136  position_error(i) = PositionError(i);
137  }
138 
139  MathLib::Vector desired_vel;
140  desired_vel.Resize(3);
141  desired_vel = gmm->getVelocity(position_error);
142 
143  Eigen::Vector3f tcpDesiredLinearVelocity;
144  tcpDesiredLinearVelocity << desired_vel(0), desired_vel(1), desired_vel(2);
145 
146  currentDesiredVelocity = scaling * tcpDesiredLinearVelocity;
147 
148 
149  float lenVec = tcpDesiredLinearVelocity.norm();
150  if (std::isnan(lenVec))
151  {
152  tcpDesiredLinearVelocity.setZero();
153  }
154 
155  if (lenVec > v_max)
156  {
157  tcpDesiredLinearVelocity = (v_max / lenVec) * tcpDesiredLinearVelocity;
158  }
159  }
160 
161  Eigen::Vector3f currentDesiredVelocity;
162  };
163 
165 
166  class DSAdaptor
167  {
168  public:
170  float epsilon;
171 
173  {
174  }
175 
176  DSAdaptor(std::vector<GMMMotionGenPtr> gmmMotionGenList, float epsilon)
177  {
178  task0_belief = 1;
179  this->gmmMotionGenList = gmmMotionGenList;
180 
181  ARMARX_INFO << "epsilon: " << epsilon;
182  this->epsilon = epsilon;
183 
184  totalDesiredVelocity.setZero();
185  }
186 
187  Eigen::Vector3f totalDesiredVelocity;
188  std::vector<GMMMotionGenPtr> gmmMotionGenList;
189 
190  void
191  updateDesiredVelocity(const Eigen::Vector3f& currentPositionInMeter,
192  float positionErrorToleranceInMeter)
193  {
194  totalDesiredVelocity.setZero();
195  for (size_t i = 0; i < gmmMotionGenList.size(); ++i)
196  {
197  gmmMotionGenList[i]->updateDesiredVelocity(currentPositionInMeter,
198  positionErrorToleranceInMeter);
200  gmmMotionGenList[i]->belief * gmmMotionGenList[i]->currentDesiredVelocity;
201  }
202  }
203 
204  void
205  updateBelief(const Eigen::Vector3f& realVelocity)
206  {
207  std::vector<float> beliefUpdate;
208  beliefUpdate.resize(gmmMotionGenList.size());
209 
210  float nullInnerSimilarity = 0;
211  for (size_t i = 0; i < gmmMotionGenList.size(); ++i)
212  {
213 
214  GMMMotionGenPtr currentGMM = gmmMotionGenList[i];
215 
216  float belief = currentGMM->belief;
217  Eigen::Vector3f OtherTasks =
218  totalDesiredVelocity - belief * currentGMM->currentDesiredVelocity;
219  float innerSimilarity = 2 * OtherTasks.dot(currentGMM->currentDesiredVelocity);
220  float outerDisSimilarity =
221  (realVelocity - currentGMM->currentDesiredVelocity).squaredNorm();
222 
223  if (innerSimilarity > nullInnerSimilarity)
224  {
225  nullInnerSimilarity = innerSimilarity;
226  }
227 
228  beliefUpdate[i] = -outerDisSimilarity - innerSimilarity;
229  }
230 
231 
232  float nullOuterSimilarity = realVelocity.squaredNorm();
233  float zeroTaskRawBeliefUpdate = -nullInnerSimilarity - nullOuterSimilarity;
234 
235  if (zeroTaskRawBeliefUpdate < 0.2)
236  {
237  zeroTaskRawBeliefUpdate -= 1000;
238  }
239 
240 
241  beliefUpdate.insert(beliefUpdate.begin(), zeroTaskRawBeliefUpdate);
242 
243  WinnerTakeAll(beliefUpdate);
244  task0_belief += epsilon * beliefUpdate[0];
245  if (task0_belief > 1)
246  {
247  task0_belief = 1;
248  }
249  else if (task0_belief < 0)
250  {
251  task0_belief = 0;
252  }
253 
254  float beliefSum = task0_belief;
255 
256  for (size_t i = 0; i < gmmMotionGenList.size(); ++i)
257  {
258  gmmMotionGenList[i]->belief += epsilon * beliefUpdate[i + 1];
259 
260 
261  if (gmmMotionGenList[i]->belief > 1)
262  {
263  gmmMotionGenList[i]->belief = 1;
264  }
265  else if (gmmMotionGenList[i]->belief < 0)
266  {
267  gmmMotionGenList[i]->belief = 0;
268  }
269 
270  beliefSum += gmmMotionGenList[i]->belief;
271  }
272 
273  for (size_t i = 0; i < gmmMotionGenList.size(); ++i)
274  {
275  gmmMotionGenList[i]->belief /= beliefSum;
276  }
277 
278  task0_belief /= beliefSum;
279  }
280 
281  private:
282  void
283  WinnerTakeAll(std::vector<float>& UpdateBeliefs_)
284  {
285  // std::fill(UpdateBeliefs_.begin(), UpdateBeliefs_.end(), 0);
286 
287  size_t winner_index = 0;
288 
289  for (size_t i = 1; i < UpdateBeliefs_.size(); i++)
290  {
291  if (UpdateBeliefs_[i] > UpdateBeliefs_[winner_index])
292  {
293  winner_index = i;
294  }
295  }
296 
297  float winner_belief = task0_belief;
298 
299  if (winner_index != 0)
300  {
301  winner_belief = gmmMotionGenList[winner_index - 1]->belief;
302  }
303 
304  if (winner_belief == 1)
305  {
306  return;
307  }
308 
309  int runnerUp_index = 0;
310 
311  if (winner_index == 0)
312  {
313  runnerUp_index = 1;
314  }
315 
316  for (size_t i = 0; i < UpdateBeliefs_.size(); i++)
317  {
318  if (i == winner_index)
319  {
320  continue;
321  }
322 
323  if (UpdateBeliefs_[i] > UpdateBeliefs_[runnerUp_index])
324  {
325  runnerUp_index = i;
326  }
327  }
328 
329  float offset = 0.5 * (UpdateBeliefs_[winner_index] + UpdateBeliefs_[runnerUp_index]);
330 
331  for (size_t i = 0; i < UpdateBeliefs_.size(); i++)
332  {
333  UpdateBeliefs_[i] -= offset;
334  }
335 
336  float UpdateSum = 0;
337 
338  for (size_t i = 0; i < UpdateBeliefs_.size(); i++)
339  {
340  float belief = task0_belief;
341  if (i != 0)
342  {
343  belief = gmmMotionGenList[i - 1]->belief;
344  }
345 
346  if (belief != 0 || UpdateBeliefs_[i] > 0)
347  {
348  UpdateSum += UpdateBeliefs_[i];
349  }
350  }
351 
352  UpdateBeliefs_[winner_index] -= UpdateSum;
353  }
354  };
355 
357 
358  /**
359  * @defgroup Library-DSRTController DSRTController
360  * @ingroup armarx_control
361  * A description of the library DSRTController.
362  *
363  * @class DSRTController
364  * @ingroup Library-DSRTController
365  * @brief Brief description of class DSRTController.
366  *
367  * Detailed description of class DSRTController.
368  */
370  public NJointControllerWithTripleBuffer<DSRTControllerControlData>,
371  public DSControllerInterface
372  {
373 
374  // ManagedIceObject interface
375  protected:
376  void onInitNJointController();
378 
379 
380  void controllerRun();
381 
382 
383  // NJointControllerInterface interface
384  public:
385  using ConfigPtrT = DSControllerConfigPtr;
386 
387  DSRTController(const RobotUnitPtr& robotUnit,
388  const NJointControllerConfigPtr& config,
389  const VirtualRobot::RobotPtr&);
390 
391  std::string
392  getClassName(const Ice::Current&) const
393  {
394  return "DSRTController";
395  }
396 
397  // NJointController interface
398  void rtRun(const IceUtil::Time& sensorValuesTimestamp,
399  const IceUtil::Time& timeSinceLastIteration);
400 
401  private:
402  // PeriodicTask<DSRTController>::pointer_type controllerTask;
403 
404  struct DSRTControllerSensorData
405  {
406  Eigen::Matrix4f tcpPose;
407  double currentTime;
408 
409  Eigen::Vector3f linearVelocity;
410  };
411 
412  TripleBuffer<DSRTControllerSensorData> controllerSensorData;
413 
414  struct DSRTDebugInfo
415  {
416  StringFloatDictionary desired_torques;
417  float desiredForce_x;
418  float desiredForce_y;
419  float desiredForce_z;
420  float tcpDesiredTorque_x;
421  float tcpDesiredTorque_y;
422  float tcpDesiredTorque_z;
423 
424  float tcpDesiredAngularError_x;
425  float tcpDesiredAngularError_y;
426  float tcpDesiredAngularError_z;
427 
428  float currentTCPAngularVelocity_x;
429  float currentTCPAngularVelocity_y;
430  float currentTCPAngularVelocity_z;
431 
432  float currentTCPLinearVelocity_x;
433  float currentTCPLinearVelocity_y;
434  float currentTCPLinearVelocity_z;
435 
436  float belief0;
437  float belief1;
438  float belief2;
439  };
440 
441  TripleBuffer<DSRTDebugInfo> debugDataInfo;
442 
443  std::vector<const SensorValue1DoFActuatorTorque*> torqueSensors;
444  std::vector<const SensorValue1DoFGravityTorque*> gravityTorqueSensors;
445  std::vector<const SensorValue1DoFActuatorVelocity*> velocitySensors;
446  std::vector<const SensorValue1DoFActuatorPosition*> positionSensors;
447 
448  std::vector<ControlTarget1DoFActuatorTorque*> targets;
449 
450 
451  VirtualRobot::RobotNodePtr tcp;
452 
453  VirtualRobot::DifferentialIKPtr ik;
454  Eigen::MatrixXf jacobip;
455  Eigen::MatrixXf jacobio;
456 
457  Eigen::Vector3f desiredPosition;
458 
459  Eigen::Quaternionf desiredQuaternion;
460  Eigen::Vector3f oldPosition;
461 
462  Eigen::Matrix3f oldOrientation;
463 
464  Eigen::Vector3f currentTCPLinearVelocity_filtered;
465  Eigen::Vector3f currentTCPAngularVelocity_filtered;
466 
467  float filterTimeConstant;
468 
469  std::vector<std::string> jointNames;
470 
471  float posiKp;
472  float v_max;
473  float posiDamping;
474  float torqueLimit;
475 
476  float oriKp;
477  float oriDamping;
478 
479  float nullspaceKp;
480  float nullspaceDamping;
481 
482  Eigen::VectorXf qnullspace;
483 
484  std::vector<GMMMotionGenPtr> gmmMotionGenList;
485 
486  DSAdaptorPtr dsAdaptorPtr;
487 
488  float positionErrorTolerance;
489 
490 
491  // NJointController interface
492  protected:
493  void onPublish(const SensorAndControl&,
496 
497  // NJointController interface
498  protected:
501  };
502 
503 } // namespace armarx::control::ds_controller
504 
505 #endif
armarx::control::ds_controller::GMRParameters::Mu_
std::vector< double > Mu_
Definition: DSRTController.h:54
armarx::DSControllerInterface
Definition: DSControllerInterface.ice:61
armarx::control::ds_controller::DSAdaptor::DSAdaptor
DSAdaptor(std::vector< GMMMotionGenPtr > gmmMotionGenList, float epsilon)
Definition: DSRTController.h:176
armarx::control::ds_controller::GMRParameters::dt_
double dt_
Definition: DSRTController.h:57
armarx::control::ds_controller::DSRTController::onDisconnectNJointController
void onDisconnectNJointController()
Definition: DSRTController.cpp:59
armarx::control::ds_controller::GMMMotionGen::belief
float belief
Definition: DSRTController.h:77
armarx::control::ds_controller::GMMMotionGen
Definition: DSRTController.h:60
boost::shared_ptr< GMRDynamics >
armarx::control::ds_controller::DSAdaptor::task0_belief
float task0_belief
Definition: DSRTController.h:169
Vector
Eigen::Matrix< T, 3, 1 > Vector
Definition: UnscentedKalmanFilterTest.cpp:39
JSONObject.h
armarx::control::ds_controller::DSRTController::getClassName
std::string getClassName(const Ice::Current &) const
Definition: DSRTController.h:392
armarx::NJointControllerWithTripleBuffer
Definition: NJointControllerWithTripleBuffer.h:10
armarx::control::ds_controller::DSRTController::rtPreActivateController
void rtPreActivateController()
This function is called before the controller is activated.
Definition: DSRTController.cpp:489
RobotUnit.h
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::control::ds_controller::GMMMotionGen::gmmParas
GMRParameters gmmParas
Definition: DSRTController.h:73
armarx::JSONObject
The JSONObject class is used to represent and (de)serialize JSON objects.
Definition: JSONObject.h:43
armarx::control::ds_controller::DSRTControllerControlData
Definition: DSRTController.h:42
armarx::control::ds_controller::DSRTController::controllerRun
void controllerRun()
Definition: DSRTController.cpp:205
armarx::control::ds_controller::DSRTController
Brief description of class DSRTController.
Definition: DSRTController.h:369
armarx::control::ds_controller::DSRTController::rtPostDeactivateController
void rtPostDeactivateController()
This function is called after the controller is deactivated.
Definition: DSRTController.cpp:494
armarx::control::ds_controller
Definition: DSJointCarryController.cpp:32
armarx::NJointControllerBase::ConfigPtrT
NJointControllerConfigPtr ConfigPtrT
Definition: NJointControllerBase.h:587
armarx::control::ds_controller::GMMMotionGen::currentDesiredVelocity
Eigen::Vector3f currentDesiredVelocity
Definition: DSRTController.h:161
armarx::control::ds_controller::GMMMotionGen::updateDesiredVelocity
void updateDesiredVelocity(const Eigen::Vector3f &currentPositionInMeter, float positionErrorToleranceInMeter)
Definition: DSRTController.h:122
armarx::control::ds_controller::GMMMotionGen::GMMMotionGen
GMMMotionGen(const std::string &fileName)
Definition: DSRTController.h:67
armarx::control::ds_controller::DSAdaptorPtr
boost::shared_ptr< DSAdaptor > DSAdaptorPtr
Definition: DSRTController.h:356
armarx::control::ds_controller::GMRParameters::attractor_
std::vector< double > attractor_
Definition: DSRTController.h:56
armarx::control::ds_controller::GMRParameters::Sigma_
std::vector< double > Sigma_
Definition: DSRTController.h:55
armarx::control::ds_controller::GMRParameters::dim_
int dim_
Definition: DSRTController.h:52
armarx::control::ds_controller::GMMMotionGen::desiredDefaultTarget
Eigen::Vector3f desiredDefaultTarget
Definition: DSRTController.h:74
IceInternal::Handle< JSONObject >
armarx::control::ds_controller::DSAdaptor::updateDesiredVelocity
void updateDesiredVelocity(const Eigen::Vector3f &currentPositionInMeter, float positionErrorToleranceInMeter)
Definition: DSRTController.h:191
GMRDynamics
Definition: GMRDynamics.h:21
armarx::detail::ControlThreadOutputBufferEntry
Definition: ControlThreadOutputBuffer.h:182
armarx::control::ds_controller::GMMMotionGen::getGMMParamsFromJsonFile
void getGMMParamsFromJsonFile(const std::string &fileName)
Definition: DSRTController.h:81
armarx::control::ds_controller::DSRTController::rtRun
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
TODO make protected and use attorneys.
Definition: DSRTController.cpp:257
armarx::control::ds_controller::DSRTControllerControlData::tcpDesiredAngularError
Eigen::Vector3f tcpDesiredAngularError
Definition: DSRTController.h:46
armarx::control::ds_controller::GMMMotionGen::gmm
GMMPtr gmm
Definition: DSRTController.h:72
ControlTarget1DoFActuator.h
Eigen::Quaternionf
Quaternion< float, 0 > Quaternionf
Definition: EigenForwardDeclarations.h:61
armarx::control::ds_controller::DSRTController::DSRTController
DSRTController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition: DSRTController.cpp:63
armarx::control::ds_controller::GMMMotionGen::GMMMotionGen
GMMMotionGen()
Definition: DSRTController.h:63
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::control::ds_controller::DSAdaptor::updateBelief
void updateBelief(const Eigen::Vector3f &realVelocity)
Definition: DSRTController.h:205
armarx::control::ds_controller::GMMMotionGenPtr
boost::shared_ptr< GMMMotionGen > GMMMotionGenPtr
Definition: DSRTController.h:164
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::control::ds_controller::DSRTControllerControlData::tcpDesiredLinearVelocity
Eigen::Vector3f tcpDesiredLinearVelocity
Definition: DSRTController.h:45
NJointController.h
armarx::control::ds_controller::DSAdaptor::DSAdaptor
DSAdaptor()
Definition: DSRTController.h:172
armarx::control::ds_controller::DSRTController::onInitNJointController
void onInitNJointController()
Definition: DSRTController.cpp:38
armarx::control::ds_controller::GMMMotionGen::v_max
float v_max
Definition: DSRTController.h:78
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::control::ds_controller::DSRTController::onPublish
void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &)
Definition: DSRTController.cpp:415
IceUtil::Handle< class RobotUnit >
armarx::control::ds_controller::DSAdaptor::epsilon
float epsilon
Definition: DSRTController.h:170
IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface >
armarx::control::ds_controller::GMRParameters::K_gmm_
int K_gmm_
Definition: DSRTController.h:51
GMRDynamics.h
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:649
armarx::control::ds_controller::GMRParameters::Priors_
std::vector< double > Priors_
Definition: DSRTController.h:53
armarx::control::ds_controller::DSAdaptor::gmmMotionGenList
std::vector< GMMMotionGenPtr > gmmMotionGenList
Definition: DSRTController.h:188
armarx::control::ds_controller::GMMMotionGen::scaling
float scaling
Definition: DSRTController.h:75
armarx::control::ds_controller::DSAdaptor
Definition: DSRTController.h:166
armarx::control::ds_controller::DSAdaptor::totalDesiredVelocity
Eigen::Vector3f totalDesiredVelocity
Definition: DSRTController.h:187
armarx::control::ds_controller::GMRParameters
Definition: DSRTController.h:49
SensorValue1DoFActuator.h
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19
armarx::TripleBuffer< DSRTControllerSensorData >