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