MP.cpp
Go to the documentation of this file.
1 #include "MP.h"
2 
3 #include <boost/archive/text_iarchive.hpp>
4 #include <boost/archive/text_oarchive.hpp>
5 #include <boost/archive/xml_iarchive.hpp>
6 #include <boost/archive/xml_oarchive.hpp>
7 
9 
10 #include "../utils.h"
11 #include <mplib/core/SystemState.h>
12 
14 {
15 
16  //MP::MP(const std::string &name, nlohmann::json &userConfig, nlohmann::json &defaultConfig)
17  MP::MP(const MPConfig& c)
18  {
19 
20  cfg = c;
21  mplib::factories::VMPFactory mpfactory;
22  mpfactory.addConfig("kernelSize", c.kernelSize);
23 
24  resetVMPType(c.mpTypeString);
25  // ARMARX_INFO << "Creating mp with name: " << c.name << "\n" << VAROUT(c.className) << "\n" << VAROUT(c.mpTypeString) << "\n" << VAROUT(c.mpMode) << "\n" << VAROUT(c.mpStyle);
26  std::shared_ptr<mplib::representation::AbstractMovementPrimitive> mp =
27  mpfactory.createMP(vmpType);
28  vmp = std::dynamic_pointer_cast<mplib::representation::vmp::PrincipalComponentVMP>(mp);
29 
30  if (cfg.viaPoints.size() > 0)
31  {
32  ARMARX_INFO << "-- adding via points: " << cfg.viaPoints.size();
33  int index = 0;
34  for (const auto& vp : cfg.viaPoints)
35  {
36  ARMARX_INFO << "---- (" << index << ") canonical value: " << vp.canonicalValue
37  << " --- " << common::dVecToString(vp.viaPointValue);
38  ARMARX_CHECK_GREATER_EQUAL(vp.canonicalValue, 0);
39  ARMARX_CHECK_LESS_EQUAL(vp.canonicalValue, 1);
40  userDefinedViaPoints.push_back({vp.canonicalValue, vp.viaPointValue});
41  index++;
42  }
43  }
44  }
45 
46  const std::string&
47  MP::getMPName() const
48  {
49  return cfg.name;
50  }
51 
52  const std::string&
54  {
55  return cfg.className;
56  }
57 
58  const std::string&
60  {
61  return cfg.nodeSetName;
62  }
63 
64  const std::string&
65  MP::getRole() const
66  {
67  return cfg.role;
68  }
69 
70  void
72  {
73  start(std::vector<double>());
74  }
75 
76  void
77  MP::start(const DVec& goals)
78  {
79  start(goals, std::vector<double>());
80  }
81 
82  void
83  MP::start(const DVec& goals, Ice::Double timeDuration)
84  {
85  cfg.durationSec = timeDuration;
86  start(goals);
87  }
88 
89  void
91  {
92  cfg.durationSec = timeDuration;
93  }
94 
95  void
96  MP::start(const DVec& goals, const DVec& starts, Ice::Double timeDuration)
97  {
98  cfg.durationSec = timeDuration;
99  start(goals, starts);
100  }
101 
102  void
103  MP::start(const DVec& goals, const DVec& starts)
104  {
105  ARMARX_INFO << "---- start " << cfg.name;
106  canonicalValue = 1.0;
107  /// parse user defined viapoints from configuration file
108  for (const auto& vp : userDefinedViaPoints)
109  {
110  setViaPoint(vp.first, vp.second);
111  // ARMARX_INFO << "viapoint at " << vp.first << " is " << common::dVecToString(vp.second);
112  }
113 
114  /// overwrite goals and starts if available
115  setStartAndGoal(starts, goals);
116 
117  /// prepare execution
118  LockGuardType guard{mpMutex};
119  vmp->prepareExecution(targetPoseVec, currentState);
120  auto vps = vmp->getViaPoints();
121  ARMARX_INFO << "---- Your MP have: ";
122  int index = 0;
123  for (const auto& v : vps)
124  {
125  ARMARX_INFO << "------ (" << index << ") viapoint at " << v.first << " --- "
127  mplib::core::SystemState::convertStatesToArray(v.second, 0));
128  index++;
129  }
130 
131  /// set flag
132  running.store(true);
133  resume();
134  ARMARX_INFO << "---- MP started: " << cfg.name;
135  }
136 
137  void
139  {
140  running.store(false);
141  }
142 
143  void
145  {
146  paused.store(true);
147  }
148 
149  void
151  {
152  paused.store(false);
153  }
154 
155  void
157  {
158  if (running.load())
159  {
160  ARMARX_INFO << "cannot reset a running mp, please stop it first.";
161  }
162  else
163  {
164  userDefinedViaPoints.clear();
165  targetPoseVec.clear();
166  targetPoseVecInTraj.clear();
167  currentState.clear();
169  goalSetByUser.store(false);
170  mpTrained.store(false);
171  }
172  }
173 
174  bool
176  {
177  return !running.load();
178  }
179 
180  bool
182  {
183  return running.load();
184  }
185 
186  bool
188  {
189  return firstRun.load();
190  }
191 
192  MPConfig
194  {
195  return cfg;
196  }
197 
198  void
199  MP::learnFromTraj(const MPTrajs& mpTrajs)
200  {
201  ARMARX_INFO << "-- Train MP '" << cfg.name << "' from trajectories";
202  MPTrajs trajList;
203  if (mpTrajs.empty())
204  {
205  ARMARX_INFO << "---- using default trajectories from the MP configuration";
206  trajList = cfg.trajectoryList;
207  }
208  else
209  {
210  ARMARX_INFO << "---- use user-provided traj";
211  trajList = mpTrajs;
212  }
213 
214  std::vector<mplib::core::SampledTrajectory> trajs;
215  for (const auto& mpTraj : trajList)
216  {
217  std::map<double, std::vector<double>> trajMap;
218  for (int i = 0; i < mpTraj.time.size(); ++i)
219  {
220  auto& row_vector = mpTraj.traj.row(i);
221  std::vector<double> vec(row_vector.data(), row_vector.data() + row_vector.size());
222  trajMap.emplace(mpTraj.time(i), vec);
223  }
224  mplib::core::SampledTrajectory traj(trajMap);
225  trajs.push_back(traj);
226  }
227  ARMARX_TRACE;
228  trainMPFromTraj(trajs);
229  }
230 
231  void
232  MP::learnFromCSV(const Ice::StringSeq& fileNames)
233  {
234  ARMARX_INFO << "-- Train MP '" << cfg.name << "' from csv files";
235  std::vector<std::string> fileList;
236  if (fileNames.empty())
237  {
238  ARMARX_INFO << "---- using default trajectory list: " << cfg.fileList[0];
239  fileList = cfg.fileList;
240  }
241  else
242  {
243  fileList = fileNames;
244  }
245 
246  std::vector<mplib::core::SampledTrajectory> trajs;
247  for (auto& file : fileList)
248  {
249  mplib::core::SampledTrajectory traj;
250  traj.readFromCSVFile(file);
251  trajs.push_back(traj);
252  }
253  trainMPFromTraj(trajs);
254  }
255 
256  void
257  MP::trainMPFromTraj(std::vector<mplib::core::SampledTrajectory>& trajs)
258  {
259  if (cfg.regressionModel == "gpr")
260  {
261  vmp->setBaseFunctionApproximator(
262  std::make_unique<mplib::math::function_approximation::GaussianProcessRegression<
263  mplib::math::kernel::SquaredExponentialCovarianceFunction>>(
264  0.01, 0.1, 0.000001));
265  for (auto& traj : trajs)
266  {
267  traj = mplib::core::SampledTrajectory::downSample(traj, 100);
268  }
269  }
270  ARMARX_TRACE;
271  vmp->learnFromTrajectories(trajs);
272  ARMARX_TRACE;
273 
274  currentState.clear();
275  targetPoseVecInTraj.clear();
276 
277  ARMARX_INFO << "---- Your trajectory has " << VAROUT(trajs[0].dim());
278  for (size_t i = 0; i < trajs[0].dim(); i++)
279  {
280  mplib::representation::MPState state(trajs[0].begin()->getPosition(i),
281  trajs[0].begin()->getDeriv(i, 1));
282  currentState.push_back(state);
283  targetPoseVecInTraj.push_back(trajs[0].rbegin()->getPosition(i));
284  }
285  ARMARX_TRACE;
286  mpTrained.store(true);
287  ARMARX_INFO << "---- MP trained";
288  }
289 
290  void
292  {
293  if (not cfg.fileList.empty())
294  {
295  learnFromCSV();
296  }
297  else if (not cfg.trajectoryList.empty())
298  {
299  learnFromTraj();
300  }
301  else
302  {
304  << "You don't provide any trajectory files (path on the robot) nor trajectories in "
305  "type std::vector<armarx::control::common::mp::arondto::MPTraj> in your "
306  "configuration file. \n"
307  << "If you intended train MPs by providing files or "
308  "trajectories on the fly, consider using \n"
309  << "ctrl.learnFromCSV(Ice::StringSeq& fileNames) or \n"
310  << "ctrl.learnFromCSVlearnFromTrajs(armarx::aron::data::dto::DictPtr& dict)";
311  }
312  }
313 
314  void
315  MP::setGoal(const DVec& goals)
316  {
317  ARMARX_INFO << "---- Reset MP goal: " << common::dVecToString(goals);
318  if (!goals.empty())
319  {
320  goalSetByUser.store(true);
321  targetPoseVec = goals;
322  }
323  else if (!targetPoseVec.empty())
324  {
326  << "---- user specified empty goal, try to use goals in your configuration file:\n"
328  }
329  else if (!targetPoseVecInTraj.empty())
330  {
332  << "---- user specified empty goal, try to use goals learned from trajectory:\n"
335  }
336  else
337  {
338  ARMARX_WARNING << "---- user specified empty goal";
339  }
340  }
341 
342  void
343  MP::setStart(const DVec& starts)
344  {
345  ARMARX_INFO << "---- Reset MP start: " << common::dVecToString(starts);
346  if (!starts.empty())
347  {
348  ARMARX_CHECK_EQUAL(starts.size(), currentState.size())
349  << ": size of starts and learned mp are not consistent";
350  for (size_t i = 0; i < currentState.size(); i++)
351  {
352  currentState[i].pos = starts[i];
353  currentState[i].vel = 0.0;
354  }
355  }
356  else
357  {
358  std::vector<double> learnedStart;
359  for (size_t i = 0; i < currentState.size(); i++)
360  {
361  learnedStart.push_back(currentState[i].pos);
362  }
363  ARMARX_INFO << "---- user doesn't define start point, fall back to start point "
364  "learned from trajectory: "
365  << common::dVecToString(learnedStart);
366  }
367  }
368 
369  std::vector<double>
371  {
372  const auto& startState = vmp->getStartState();
373  std::vector<double> mpStartVec;
374  for (const auto& state : startState)
375  {
376  mpStartVec.push_back(state.pos);
377  }
378  return mpStartVec;
379  }
380 
381  void
382  MP::setStartAndGoal(const DVec& starts, const DVec& goals)
383  {
384  setStart(starts);
385  setGoal(goals);
386  }
387 
388  void
389  MP::setViaPoint(Ice::Double canVal, const DVec& viapoint)
390  {
391  if (mpTrained.load())
392  {
393  LockGuardType guard{mpMutex};
394  if (canVal <= vmp->getUmin())
395  {
396  setGoal(viapoint);
397  }
398  else if (canVal >= 1.0 - vmp->getUmin())
399  {
400  setStart(viapoint);
401  }
402  else
403  {
404  vmp->setViaPoint(canVal, viapoint);
405  }
406  }
407  else
408  {
409  ARMARX_ERROR << " -- mp is not trained yet, potential memory allocation error! "
410  "Please train mp before setting any via points";
411  }
412  }
413 
414  void
416  {
417  LockGuardType guard{mpMutex};
418  vmp->removeViaPoints();
419  }
420 
421  double
423  {
424  return canonicalValue;
425  }
426 
427  /// serialze
428  void
429  MP::setWeight(const DVecVec& weights)
430  {
431  vmp->setWeights(weights);
432  }
433 
434  DVecVec
436  {
437  return vmp->getWeights();
438  }
439 
440  std::string
441  MP::serialize(const std::string& mode)
442  {
443  // std::stringstream ss;
444  // if (mode == "string")
445  // {
446  // boost::archive::text_oarchive oa{ss};
447  // oa << vmp.get();
448  // }
449  // else if (mode == "xml")
450  // {
451  // boost::archive::xml_oarchive oa(ss);
452  // oa << vmp.get();
453  // }
454  // return ss.str();
455  return "";
456  }
457 
458  DVec
459  MP::deserialize(const std::string& mpString, const std::string& mode)
460  {
461  // std::stringstream ss;
462  // ss.str(mpString);
463  // mplib::representation::vmp::PrincipalComponentVMP* dmpPointer;
464  // if (mode == "string")
465  // {
466  // boost::archive::text_iarchive ia{ss};
467  // ia >> dmpPointer;
468  // }
469  // else if (mode == "xml")
470  // {
471  // boost::archive::xml_iarchive ia(ss);
472  // ia >> dmpPointer;
473  // }
474  // else
475  // {
476  // ARMARX_ERROR << VAROUT(mode) << " unsupported! please use 'string' or 'xml' mode";
477  // }
478  // vmp.reset(dmpPointer);
479  return vmp->getGoals();
480  }
481 
482 } // namespace armarx::control::common::mp
armarx::control::common::mp::MP::reset
void reset()
Definition: MP.cpp:156
armarx::control::common::mp::MP::getMPName
const std::string & getMPName() const
Definition: MP.cpp:47
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::control::common::mp::MP::getWeight
DVecVec getWeight()
Definition: MP.cpp:435
armarx::control::common::mp::MP::canonicalValue
double canonicalValue
Definition: MP.h:145
armarx::control::common::mp::MP::getRole
const std::string & getRole() const
Definition: MP.cpp:65
armarx::control::common::mp::DVecVec
DoubleSeqSeq DVecVec
Definition: MP.h:47
armarx::control::common::mp::MP::trainMPFromTraj
void trainMPFromTraj(std::vector< mplib::core::SampledTrajectory > &trajs)
Definition: MP.cpp:257
armarx::control::common::mp::MP::trainMP
void trainMP()
Definition: MP.cpp:291
armarx::control::common::mp::MP::learnFromCSV
void learnFromCSV(const Ice::StringSeq &fileNames=std::vector< std::string >())
setting
Definition: MP.cpp:232
armarx::control::common::mp::MP::setDurationSec
void setDurationSec(Ice::Double timeDuration)
Definition: MP.cpp:90
armarx::control::common::mp::MP::stop
void stop()
Definition: MP.cpp:138
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::control::common::mp::MP::pause
void pause()
Definition: MP.cpp:144
armarx::control::common::mp::MP::deserialize
DVec deserialize(const std::string &, const std::string &mode="string")
Definition: MP.cpp:459
armarx::control::common::mp::MP::targetPoseVecInTraj
DVec targetPoseVecInTraj
Definition: MP.h:153
armarx::control::common::mp
This file is part of ArmarX.
Definition: aron_conversions.cpp:331
armarx::control::common::mp::MP::getConfig
MPConfig getConfig()
Definition: MP.cpp:193
armarx::control::common::mp::MP::mpTrained
std::atomic_bool mpTrained
Note: if mp is not trained, the dimension is not initialized, thus mp->getDim() is undefined,...
Definition: MP.h:151
armarx::control::common::mp::MP::setStart
void setStart(const DVec &starts)
Definition: MP.cpp:343
armarx::control::common::mp::MP::firstRun
std::atomic_bool firstRun
Definition: MP.h:146
armarx::control::common::mp::MP::MP
MP(const MPConfig &c)
Definition: MP.cpp:17
armarx::control::common::mp::MP::cfg
MPConfig cfg
Definition: MP.h:134
armarx::control::common::mp::LockGuardType
std::lock_guard< std::recursive_mutex > LockGuardType
Definition: MP.h:44
MP.h
armarx::control::common::mp::MP::userDefinedViaPoints
std::vector< std::pair< double, DVec > > userDefinedViaPoints
Definition: MP.h:155
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
armarx::control::common::dVecToString
std::string dVecToString(const mplib::core::DVec &dvec)
Definition: utils.cpp:289
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
armarx::control::common::mp::MP::getCanonicalValue
double getCanonicalValue()
Definition: MP.cpp:422
armarx::control::common::mp::MP::serialize
std::string serialize(const std::string &mode="string")
Definition: MP.cpp:441
armarx::control::common::mp::MP::setGoal
void setGoal(const DVec &goals)
Definition: MP.cpp:315
armarx::control::common::mp::DVec
Ice::DoubleSeq DVec
Definition: MP.h:46
armarx::control::common::mp::MP::goalSetByUser
std::atomic_bool goalSetByUser
Definition: MP.h:148
armarx::control::common::mp::MP::paused
std::atomic_bool paused
Definition: MP.h:144
armarx::control::common::mp::MP::vmp
VMPPtr vmp
Definition: MP.h:139
armarx::control::common::mp::MP::currentState
std::vector< mplib::representation::MPState > currentState
Definition: MP.h:154
armarx::control::common::mp::MP::removeAllViaPoint
void removeAllViaPoint()
Definition: MP.cpp:415
armarx::control::common::mp::MP::isRunning
bool isRunning()
Definition: MP.cpp:181
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::control::common::mp::MP::learnFromTraj
void learnFromTraj(const MPTrajs &trajs=MPTrajs())
Definition: MP.cpp:199
ARMARX_CHECK_GREATER_EQUAL
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
Definition: ExpressionException.h:123
ARMARX_CHECK_LESS_EQUAL
#define ARMARX_CHECK_LESS_EQUAL(lhs, rhs)
This macro evaluates whether lhs is less or equal (<=) rhs and if it turns out to be false it will th...
Definition: ExpressionException.h:109
armarx::control::common::mp::MP::getNodeSetName
const std::string & getNodeSetName() const
Definition: MP.cpp:59
ExpressionException.h
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::control::common::mp::MP::getStartVec
std::vector< double > getStartVec()
Definition: MP.cpp:370
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::control::common::mp::MP::isFirstRun
bool isFirstRun()
Definition: MP.cpp:187
armarx::control::common::mp::MPTrajs
std::vector< MPTraj > MPTrajs
Definition: MP.h:65
armarx::control::common::mp::MP::start
void start()
control
Definition: MP.cpp:71
armarx::control::common::mp::MP::vmpType
mplib::representation::VMPType vmpType
Definition: MP.h:140
armarx::control::common::mp::MP::setWeight
void setWeight(const DVecVec &weights)
serialze
Definition: MP.cpp:429
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::control::common::mp::MP::isFinished
bool isFinished()
status
Definition: MP.cpp:175
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::control::common::mp::MP::mpMutex
MutexType mpMutex
Definition: MP.h:138
armarx::control::common::mp::MP::setViaPoint
void setViaPoint(Ice::Double u, const DVec &viapoint)
Definition: MP.cpp:389
armarx::control::common::mp::MP::getClassName
const std::string & getClassName() const
Definition: MP.cpp:53
armarx::control::common::mp::MP::resume
void resume()
Definition: MP.cpp:150
armarx::control::common::mp::MP::targetPoseVec
DVec targetPoseVec
Definition: MP.h:152
armarx::control::common::mp::MP::running
std::atomic_bool running
Definition: MP.h:142
armarx::control::common::mp::MP::setStartAndGoal
void setStartAndGoal(const DVec &starts, const DVec &goals)
Definition: MP.cpp:382