DMPInstance.cpp
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 RobotAPI::ArmarXObjects::DMPComponent
17  * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
18  * @date 2015
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 
24 #include "DMPInstance.h"
25 
26 #include <Ice/ObjectAdapter.h>
27 
28 #include <dmp/io/MMMConverter.h>
29 
30 using namespace armarx;
31 
32 // tool functions
33 DMP::Vec<DMP::DMPState>
34 getDMPStateFromcStateVec(const cStateVec& state)
35 {
36  DMP::Vec<DMP::DMPState> res;
37  res.resize(state.size());
38 
39  for (size_t i = 0; i < state.size(); i++)
40  {
41  res[i].pos = state[i].pos;
42  res[i].vel = state[i].vel;
43  }
44 
45  return res;
46 }
47 
48 DMP::DVec2d
49 getDVec2dStateFromcStateVec(const cStateVec& state)
50 {
51  DMP::DVec2d res;
52  res.resize(state.size());
53  for (size_t i = 0; i < state.size(); i++)
54  {
55  res[i].push_back(state[i].pos);
56  res[i].push_back(state[i].vel);
57  }
58 
59  return res;
60 }
61 
62 armarx::cStateVec
63 getcStateVec(const DMP::Vec<DMP::DMPState>& dmpstate)
64 {
65  armarx::cStateVec sv;
66  sv.resize(dmpstate.size());
67 
68  for (size_t i = 0; i < dmpstate.size(); i++)
69  {
70  sv[i].pos = dmpstate[i].pos;
71  sv[i].vel = dmpstate[i].vel;
72  }
73 
74  return sv;
75 }
76 
77 armarx::cStateVec
78 getcStateVec(const DMP::DVec2d& dmpstate)
79 {
80  armarx::cStateVec sv;
81  sv.resize(dmpstate.size());
82 
83  for (size_t i = 0; i < dmpstate.size(); i++)
84  {
85  sv[i].pos = dmpstate[i].at(0);
86  sv[i].vel = dmpstate[i].at(1);
87  }
88 
89  return sv;
90 }
91 
92 DMPInstance::DMPInstance(DMP::DMPInterfacePtr dmpInter, std::string DMPType)
93 {
94  dmp = dmpInter;
95  dmpType = DMPType;
96  ctime = 0;
97  timestep = 0.001;
98 }
99 
100 // state calculation
101 
102 cStateVec
103 DMPInstance::getNextState(const cStateVec& states, const Ice::Current&)
104 {
105  if (canonicalValues.size() == 0)
106  {
107  ARMARX_WARNING << "Canonical value is not specified. It will be set 1.0.";
108  canonicalValues.push_back(1.0);
109  }
110 
111  DMP::DVec2d currentDMPState = getDVec2dStateFromcStateVec(states);
112  if (currentDMPState.size() == 0)
113  {
114  ARMARX_ERROR << "The current state is not available. Please specify current state with "
115  "setDMPState().";
116  }
117 
118  DMP::DVec goal = dmp->getGoals();
119 
120 
121  ARMARX_INFO << "CanonicalValues: " << canonicalValues[0] << " ctime: " << ctime
122  << " Timestep: " << timestep;
123  double temporalFactor = dmp->getTemporalFactor();
124  currentDMPState = dmp->calculateTrajectoryPointBase(
125  ctime + timestep, goal, ctime, currentDMPState, canonicalValues, temporalFactor);
126 
127  ctime += timestep;
128  cStateVec nextState = getcStateVec(currentDMPState);
129  setDMPState(nextState);
130  ARMARX_INFO << "Got next state";
131 
132  return nextState;
133 }
134 
135 armarx::nStateValues
137  const Ice::DoubleSeq& goal,
138  double currentT,
139  const Vec2D& currentStates,
140  const Ice::DoubleSeq& canonicalValues,
141  double temporalFactor,
142  const ::Ice::Current&)
143 {
144  if (canonicalValues.size() == 0)
145  {
146  ARMARX_ERROR << "Canonical value is not specified.";
147  // canonicalValues.push_back(1.0);
148  }
149 
150  if (currentStates.size() == 0)
151  {
152  ARMARX_ERROR << "Current DMP State has to be specified";
153  }
154 
155  DMP::DVec goal_v = DMP::DVec(goal);
156 
157  if (goal.size() == 0)
158  {
159  ARMARX_WARNING << "Using goal specified in configs";
160  goal_v = getGoal();
161  }
162 
163  DMP::DVec2d curStates;
164 
165  for (std::size_t i = 0; i < currentStates.size(); ++i)
166  {
167  curStates.emplace_back(DMP::DVec(currentStates.at(i)));
168  }
169 
170  DMP::DVec canValues = DMP::DVec(canonicalValues);
171  ARMARX_INFO_S << VAROUT(temporalFactor);
172  DMP::DVec2d tmp_result = dmp->calculateTrajectoryPointBase(
173  t, goal_v, currentT, curStates, canValues, temporalFactor);
174 
175  Ice::DoubleSeq tmpCanVal;
176  for (std::size_t i = 0; i < canValues.size(); i++)
177  {
178  tmpCanVal.emplace_back(canValues.at(i));
179  }
180 
181  nStateValues result;
182 
183  result.canonicalValues = tmpCanVal;
184 
185  Vec2D nState;
186  for (std::size_t i = 0; i < tmp_result.size(); ++i)
187  {
188  ::Ice::DoubleSeq dblseq = ::Ice::DoubleSeq(tmp_result.at(i));
189 
190  nState.emplace_back(dblseq);
191  }
192 
193  result.nextState = nState;
194 
195  return result;
196 }
197 
198 armarx::nStateValues
200  double currentT,
201  const Vec2D& currentStates,
202  const Ice::DoubleSeq& canonicalValues,
203  const Ice::Current&)
204 {
205  DMP::DVec goal = getGoal();
206  double temporalFactor = getTemporalFactor();
207  return calcNextState(t, goal, currentT, currentStates, canonicalValues, temporalFactor);
208 }
209 
210 // configuration & parameters
211 void
212 DMPInstance::setConfigurationMap(const DMPConfigMap& conf, const Ice::Current&)
213 {
214  std::map<std::string, paraType> configMap;
215  for (::std::map<::std::string, ::Ice::DoubleSeq>::const_iterator it = conf.begin();
216  it != conf.end();
217  ++it)
218  {
219  configMap[it->first] = (DMP::DVec)it->second;
220  dmp->setConfiguration(it->first, it->second);
221  }
222 
223  configs = configMap;
224 }
225 
226 configMap
227 DMPInstance::createConfigMap(DMP::Vec<std::string> paraIDs, DMP::Vec<paraType> paraVals)
228 {
229  if (paraIDs.size() != paraVals.size())
230  {
231  ARMARX_WARNING << "ID list and value list have different sizes, which may cause error.";
232  }
233 
235  for (size_t i = 0; i < paraIDs.size(); i++)
236  {
237  if (configs.find(paraIDs[i]) == configs.end())
238  {
239  configs.insert(configPair(paraIDs[i], paraVals[i]));
240  }
241  else
242  {
243  configs[paraIDs[i]] = paraVals[i];
244  }
245  }
246 
247  return configs;
248 }
249 
250 void
251 DMPInstance::setParameter(const std::string& paraID,
252  const Ice::DoubleSeq& value,
253  const ::Ice::Current&)
254 {
255  if (configs.find(paraID) == configs.end())
256  {
257  configs.insert(configPair(paraID, value));
258  }
259  else
260  {
261  configs[paraID] = value;
262  }
263  dmp->setConfiguration(paraID, DMP::DVec(value));
264 }
265 
266 // setter functions
267 
268 void
269 DMPInstance::setCanonicalValues(const Ice::DoubleSeq& value, const Ice::Current&)
270 {
272 }
273 
274 void
275 DMPInstance::setAmpl(int dim, double value, const Ice::Current&)
276 {
277  dmp->setAmpl(dim, value);
278 }
279 
280 void
281 DMPInstance::setTemporalFactor(double value, const Ice::Current&)
282 {
283  dmp->setTemporalFactor(value);
284 }
285 
286 void
287 DMPInstance::setGoal(const Ice::DoubleSeq& value, const Ice::Current&)
288 {
289  if (configs.find(DMP::Goal) == configs.end())
290  {
291  configs.insert(configPair(DMP::Goal, DMP::DVec(value)));
292  }
293  else
294  {
295  configs[DMP::Goal] = DMP::DVec(value);
296  }
297  dmp->setConfiguration(DMP::Goal, DMP::DVec(value));
298 }
299 
300 void
301 DMPInstance::setStartPosition(const Ice::DoubleSeq& value, const Ice::Current&)
302 {
303  if (configs.find(DMP::StartPosition) == configs.end())
304  {
305  configs.insert(configPair(DMP::StartPosition, DMP::DVec(value)));
306  }
307  else
308  {
309  configs[DMP::StartPosition] = DMP::DVec(value);
310  }
311  dmp->setConfiguration(DMP::StartPosition, DMP::DVec(value));
312 }
313 
314 void
315 DMPInstance::setDMPState(const cStateVec& state, const Ice::Current&)
316 {
317  dmpState = state;
318 }
319 
320 // getter function
321 
322 double
323 DMPInstance::getAmpl(int dim, const Ice::Current&)
324 {
325  return dmp->getAmpl(dim);
326 }
327 
328 double
329 DMPInstance::getTemporalFactor(const Ice::Current&)
330 {
331  return dmp->getTemporalFactor();
332 }
333 
334 double
335 DMPInstance::getForceTerm(const Ice::DoubleSeq& canVal, int dim, const Ice::Current&)
336 {
337  return dmp->_getPerturbationForce(dim, canVal[0]);
338 }
339 
340 Ice::DoubleSeq
341 DMPInstance::getGoal(const Ice::Current&)
342 {
343  DMP::DVec goals = dmp->getGoals();
344  Ice::DoubleSeq res;
345 
346  for (size_t i = 0; i < goals.size(); ++i)
347  {
348  res.push_back(goals.at(i));
349  }
350 
351  return res;
352 }
353 
354 // trajectory related
355 
356 Ice::DoubleSeq
357 DMPInstance::getTrajGoal(const ::Ice::Current&)
358 {
359  Ice::DoubleSeq trajGoal;
360  for (size_t i = 0; i < trajs[0].dim(); i++)
361  {
362  trajGoal.push_back(trajs[0].rbegin()->getPosition(i));
363  }
364 
365  return trajGoal;
366 }
367 
368 cStateVec
369 DMPInstance::getTrajStartState(const ::Ice::Current&)
370 {
371  cStateVec startState;
372 
373  for (size_t i = 0; i < trajs[0].dim(); i++)
374  {
375  cState state;
376  state.pos = trajs[0].begin()->getPosition(i);
377  state.vel = trajs[0].begin()->getDeriv(i, 1);
378  state.acc = trajs[0].begin()->getDeriv(i, 2);
379 
380  startState.push_back(state);
381  }
382 
383  return startState;
384 }
385 
386 void
387 DMPInstance::readTrajectoryFromFile(const std::string& file, double times, const Ice::Current&)
388 {
389  std::string ext = file.rfind(".") == file.npos ? file : file.substr(file.rfind(".") + 1);
390 
391  if (ext == "xml")
392  {
393 
394 
395  ARMARX_INFO << "xml file loaded";
396  }
397  else if (ext == "csv")
398  {
399  DMP::SampledTrajectoryV2 traj;
400  traj.readFromCSVFile(file);
401  traj.gaussianFilter(0.01);
402 
403  double startTime = 0;
404  double endTime = times;
405  traj = DMP::SampledTrajectoryV2::normalizeTimestamps(traj, startTime, endTime);
406 
407 
408  trajs.push_back(traj);
409  dmp->setDim(traj.dim());
410 
411  ARMARX_INFO << "csv file loaded";
412  }
413  else if (ext == "vsg")
414  {
415  }
416  else
417  {
418  ARMARX_ERROR << "Error: The file is not valid ";
419  }
420 }
421 
422 // DMP Trainer
423 void
424 DMPInstance::trainDMP(const Ice::Current&)
425 {
426  dmp->learnFromTrajectories(trajs);
427 }
428 
429 Vec2D
431  double timeStep,
432  double endTime,
433  const ::Ice::DoubleSeq& goal,
434  const cStateVec& states,
435  const ::Ice::DoubleSeq& canonicalValues,
436  double temporalFactor,
437  const Ice::Current&)
438 {
439  setDMPState(states);
440  setGoal(goal);
442  setTemporalFactor(temporalFactor);
443  setCurrentTime(startTime);
444  setTimeStep(timeStep);
445 
446  Vec2D resultingTrajectory;
447 
448  cStateVec nextStates = states;
449  while (ctime < endTime)
450  {
451  nextStates = getNextState(nextStates);
452  ::Ice::DoubleSeq positions;
453 
454  positions.push_back(ctime);
455  for (unsigned int d = 0; d < states.size(); d++)
456  {
457  positions.push_back(nextStates.at(d).pos);
458  }
459 
460  resultingTrajectory.push_back(positions);
461  }
462 
463  setCurrentTime(0);
464 
465  return resultingTrajectory;
466 }
467 
468 Vec2D
469 DMPInstance::calcTrajectoryV2(const Ice::DoubleSeq& timestamps,
470  const Ice::DoubleSeq& goal,
471  const Vec2D& initStates,
472  const Ice::DoubleSeq& canonicalValues,
473  double temporalFactor,
474  const Ice::Current&)
475 {
476  DMP::DVec timestampsLocal = timestamps;
477 
478  if (timestampsLocal.size() == 0)
479  {
480  ARMARX_ERROR << "No Timestamps specified";
481  }
482 
483  DMP::DVec::const_iterator it = timestamps.begin();
484  Vec2D previousState = initStates;
485  Vec2D resultingTrajectory;
486  // std::map<double, DMP::DVec > resultingSystemStatesMap;
487 
488  //DMP::DVec canonicalValues = initialCanonicalValues;
489  double prevTimestamp = *it;
490 
491  Ice::DoubleSeq canValues = canonicalValues;
492 
493  for (; it != timestamps.end(); it++)
494  {
495  nStateValues nState =
496  calcNextState(*it, goal, prevTimestamp, previousState, canValues, temporalFactor);
497  canValues = nState.canonicalValues;
498  previousState = nState.nextState;
499 
500  prevTimestamp = *it;
501  ::Ice::DoubleSeq positions;
502  for (unsigned int d = 0; d < previousState.size(); d++)
503  {
504  positions.push_back(previousState.at(d)[0]);
505  }
506  resultingTrajectory.push_back(positions);
507  }
508 
509  return resultingTrajectory;
510 }
511 
512 Vec2D
513 DMPInstance::calcTrajectoryFromConfig(const Ice::DoubleSeq& timestamps,
514  const Vec2D& initStates,
515  const Ice::DoubleSeq& canonicalValues,
516  const Ice::Current&)
517 {
518  DMP::DVec goal = getGoal();
519  double temporalFactor = getTemporalFactor();
520  return calcTrajectoryV2(timestamps, goal, initStates, canonicalValues, temporalFactor);
521 }
armarx::DMPInstance::trainDMP
void trainDMP(const ::Ice::Current &=Ice::emptyCurrent) override
Definition: DMPInstance.cpp:424
getDVec2dStateFromcStateVec
DMP::DVec2d getDVec2dStateFromcStateVec(const cStateVec &state)
Definition: DMPInstance.cpp:49
armarx::configMap
std::map< std::string, paraType > configMap
Definition: DMPInstance.h:67
armarx::DMPInstance::calcTrajectoryFromConfig
Vec2D calcTrajectoryFromConfig(const Ice::DoubleSeq &timestamps, const Vec2D &initStates, const Ice::DoubleSeq &canonicalValues, const Ice::Current &=Ice::emptyCurrent) override
Definition: DMPInstance.cpp:513
armarx::DMPInstance::calcTrajectoryV2
Vec2D calcTrajectoryV2(const Ice::DoubleSeq &timestamps, const Ice::DoubleSeq &goal, const Vec2D &initStates, const Ice::DoubleSeq &canonicalValues, double temporalFactor, const Ice::Current &=Ice::emptyCurrent) override
Definition: DMPInstance.cpp:469
armarx::DMPInstance::getAmpl
double getAmpl(int dim, const ::Ice::Current &=Ice::emptyCurrent) override
getAmpl: get current amplitude of a dimension
Definition: DMPInstance.cpp:323
armarx::DMPInstance::configs
configMap configs
Definition: DMPInstance.h:364
armarx::DMPInstance::setDMPState
void setDMPState(const cStateVec &state, const ::Ice::Current &=Ice::emptyCurrent) override
setDMPState set current state for dmp
Definition: DMPInstance.cpp:315
armarx::DMPInstance::setParameter
void setParameter(const std::string &paraId, const Ice::DoubleSeq &value, const ::Ice::Current &=Ice::emptyCurrent) override
setParameter set parameters for
Definition: DMPInstance.cpp:251
DMPInstance.h
armarx::DMPInstance::ctime
double ctime
Definition: DMPInstance.h:365
armarx::DMPInstance::dmp
DMP::DMPInterfacePtr dmp
Definition: DMPInstance.h:363
armarx::DMPInstance::setTemporalFactor
void setTemporalFactor(double value, const ::Ice::Current &=Ice::emptyCurrent) override
setTemporalFactor: set dmp temporal factor
Definition: DMPInstance.cpp:281
armarx::DMPInstance::setStartPosition
void setStartPosition(const Ice::DoubleSeq &value, const ::Ice::Current &=Ice::emptyCurrent) override
setStartPosition set the start position for dmp
Definition: DMPInstance.cpp:301
armarx::DMPInstance::getTrajStartState
cStateVec getTrajStartState(const ::Ice::Current &=Ice::emptyCurrent) override
getTrajStartState: get the start state of the training trajectory
Definition: DMPInstance.cpp:369
armarx::DMPInstance::setConfigurationMap
void setConfigurationMap(const DMPConfigMap &value, const ::Ice::Current &=Ice::emptyCurrent) override
setConfigurationMap set dmp configurations using configMap
Definition: DMPInstance.cpp:212
getcStateVec
armarx::cStateVec getcStateVec(const DMP::Vec< DMP::DMPState > &dmpstate)
Definition: DMPInstance.cpp:63
armarx::configPair
std::pair< std::string, paraType > configPair
Definition: DMPInstance.h:68
armarx::DMPInstance::readTrajectoryFromFile
void readTrajectoryFromFile(const std::string &file, double times=1, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: DMPInstance.cpp:387
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::DMPInstance::setTimeStep
void setTimeStep(double ts)
Definition: DMPInstance.h:321
armarx::DMPInstance::calcNextState
nStateValues calcNextState(double t, const Ice::DoubleSeq &goal, double currentT, const Vec2D &currentStates, const Ice::DoubleSeq &canonicalValues, double temporalFactor, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: DMPInstance.cpp:136
armarx::DMPInstance::getTrajGoal
Ice::DoubleSeq getTrajGoal(const ::Ice::Current &=Ice::emptyCurrent) override
getTrajGoal: get the goal of the training trajectory
Definition: DMPInstance.cpp:357
normalizeTimestamps
TrajectoryPtr normalizeTimestamps(TrajectoryPtr t, float maxTransVel, float maxRotVel)
Definition: PlayPlatformTrajectory.cpp:82
armarx::DMPInstance::dmpState
cStateVec dmpState
Definition: DMPInstance.h:372
armarx::control::common::mp::DVec
Ice::DoubleSeq DVec
Definition: MP.h:47
armarx::DMPInstance::calcTrajectory
Vec2D calcTrajectory(double startTime, double timestep, double endTime, const ::Ice::DoubleSeq &goal, const cStateVec &initStates, const ::Ice::DoubleSeq &canonicalValues, double temporalFactor, const Ice::Current &=Ice::emptyCurrent) override
calcTrajectory solves the DMP for all Timesteps
Definition: DMPInstance.cpp:430
armarx::DMPInstance::getGoal
Ice::DoubleSeq getGoal(const Ice::Current &=Ice::emptyCurrent)
Definition: DMPInstance.cpp:341
armarx::DMPInstance::canonicalValues
DMP::DVec canonicalValues
Definition: DMPInstance.h:371
armarx::DMPInstance::trajs
TrajVec trajs
Definition: DMPInstance.h:369
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::DMPInstance::setCurrentTime
void setCurrentTime(double t)
Definition: DMPInstance.h:327
getDMPStateFromcStateVec
DMP::Vec< DMP::DMPState > getDMPStateFromcStateVec(const cStateVec &state)
Definition: DMPInstance.cpp:34
armarx::DMPInstance::dmpType
std::string dmpType
Definition: DMPInstance.h:362
armarx::DMPInstance::getNextState
cStateVec getNextState(const cStateVec &states, const ::Ice::Current &=Ice::emptyCurrent) override
getNextState: get next state according to the state given
Definition: DMPInstance.cpp:103
armarx::DMPInstance::setGoal
void setGoal(const Ice::DoubleSeq &value, const ::Ice::Current &=Ice::emptyCurrent) override
setGoal set the goal for dmp
Definition: DMPInstance.cpp:287
armarx::DMPInstance::calcNextStateFromConfig
nStateValues calcNextStateFromConfig(double t, double currentT, const Vec2D &currentStates, const Ice::DoubleSeq &canonicalValues, const Ice::Current &=Ice::emptyCurrent) override
Definition: DMPInstance.cpp:199
armarx::DMPInstance::getForceTerm
double getForceTerm(const Ice::DoubleSeq &canVal, int dim, const ::Ice::Current &=Ice::emptyCurrent) override
getForceTerm: get force termf for one dimension at a specified canonical values
Definition: DMPInstance.cpp:335
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::DMPInstance::createConfigMap
configMap createConfigMap(DMP::Vec< std::string > paraIDs, DMP::Vec< paraType > paraVals)
Definition: DMPInstance.cpp:227
armarx::DMPInstance::setAmpl
void setAmpl(int dim, double value, const ::Ice::Current &=Ice::emptyCurrent) override
setAmpl: set amplitude for dmp
Definition: DMPInstance.cpp:275
armarx::DMPInstance::DMPInstance
DMPInstance()
DMPInstance constructs an empty instance of a basicDMP.
Definition: DMPInstance.h:87
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
armarx::DMPInstance::getTemporalFactor
double getTemporalFactor(const ::Ice::Current &=Ice::emptyCurrent) override
getTemporalFactor: get current temporal factor
Definition: DMPInstance.cpp:329
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::DMPInstance::setCanonicalValues
void setCanonicalValues(const Ice::DoubleSeq &value, const ::Ice::Current &=Ice::emptyCurrent) override
setCanonicalValues: set dmp canonicalValues to control the dmp's state
Definition: DMPInstance.cpp:269
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::DMPInstance::timestep
double timestep
Definition: DMPInstance.h:367