3 #include <boost/archive/text_iarchive.hpp>
4 #include <boost/archive/text_oarchive.hpp>
8 #include <VirtualRobot/Robot.h>
19 #include <armarx/control/deprecated_njoint_mp_controller/joint_space/ControllerInterface.h>
21 #include <dmp/representation/dmp/umidmp.h>
26 NJointControllerRegistration<NJointJSDMPController>
32 return "NJointJSDMPController";
36 const armarx::NJointControllerConfigPtr& config,
39 ARMARX_INFO <<
"creating joint space dmp controller ... ";
42 cfg = NJointJointSpaceDMPControllerConfigPtr::dynamicCast(config);
45 for (std::string jointName : cfg->jointNames)
49 targets.insert(std::make_pair(jointName, ct->
asA<ControlTarget1DoFActuatorVelocity>()));
50 positionSensors.insert(
51 std::make_pair(jointName, sv->
asA<SensorValue1DoFActuatorPosition>()));
52 velocitySensors.insert(
53 std::make_pair(jointName, sv->
asA<SensorValue1DoFActuatorVelocity>()));
55 if (cfg->jointNames.size() == 0)
60 <<
" baseMode: " << cfg->baseMode;
62 dmpPtr.reset(
new DMP::UMIDMP(cfg->kernelSize, 100, cfg->baseMode, 1));
63 timeDuration = cfg->timeDuration;
66 phaseDist0 = cfg->phaseDist0;
67 phaseDist1 = cfg->phaseDist1;
68 phaseKp = cfg->phaseKp;
69 dimNames = cfg->jointNames;
72 targetVels.resize(cfg->jointNames.size());
75 for (
size_t i = 0; i < cfg->jointNames.size(); ++i)
84 NJointJSDMPControllerSensorData initSensorData;
85 initSensorData.currentTime = 0;
86 initSensorData.deltaT = 0;
87 initSensorData.currentState.resize(cfg->jointNames.size());
92 qpos.resize(dimNames.size());
93 qvel.resize(dimNames.size());
99 if (!started || finished)
101 for (
size_t i = 0; i < dimNames.size(); ++i)
113 double phaseStop = 0;
114 double mpcFactor = 1;
116 std::vector<double> currentPosition;
118 currentPosition.resize(dimNames.size());
120 for (
size_t i = 0; i < currentState.size(); i++)
122 DMP::DMPState currentPos = currentState[i];
123 currentPosition[i] = currentPos.pos;
124 error += pow(currentPos.pos - targetState[i], 2);
127 if (cfg->isPhaseStop)
133 phaseDist = phaseDist1;
137 phaseDist = phaseDist0;
141 phaseStop = phaseL / (1 + exp(-phaseK * (error - phaseDist)));
142 mpcFactor = 1 - (phaseStop / phaseL);
146 isDisturbance =
true;
151 isDisturbance =
false;
155 canVal -= tau * deltaT * 1 / (1 + phaseStop);
156 double dmpDeltaT = deltaT / timeDuration;
158 currentDMPState = dmpPtr->calculateDirectlyVelocity(
159 currentDMPState, canVal / timeDuration, dmpDeltaT, targetState);
161 for (
size_t i = 0; i < currentDMPState.size(); ++i)
163 double vel0 = tau * currentDMPState[i].vel / timeDuration;
164 double vel1 = phaseKp * (targetState[i] - currentPosition[i]);
166 double vel = vel1 + vel0;
168 debugOutputData.
getWriteBuffer().latestTargetVelocities[dimNames[i]] =
171 (
float)currentDMPState[i].pos;
181 for (
size_t i = 0; i < dimNames.size(); ++i)
197 for (
size_t i = 0; i < dimNames.size(); i++)
199 const auto& jointName = dimNames.at(i);
200 DMP::DMPState currentPos;
201 currentPos.pos = (positionSensors.count(jointName) == 1)
202 ? positionSensors[jointName]->position
204 currentPos.vel = (velocitySensors.count(jointName) == 1)
205 ? velocitySensors[jointName]->velocity
207 qpos[i] = currentPos.pos;
208 qvel[i] = currentPos.vel;
209 controllerSensorData.
getWriteBuffer().currentState[i] = currentPos;
211 controllerSensorData.
getWriteBuffer().deltaT = timeSinceLastIteration.toSecondsDouble();
213 timeSinceLastIteration.toSecondsDouble();
224 for (
size_t i = 0; i < dimNames.size(); ++i)
227 if (fabs(targetJointVels[i]) > cfg->maxJointVel)
229 targets[dimNames[i]]->velocity =
230 targetJointVels[i] < 0 ? -cfg->maxJointVel : cfg->maxJointVel;
234 targets[dimNames[i]]->velocity = targetJointVels[i];
242 DMP::Vec<DMP::SampledTrajectoryV2> trajs;
245 for (
size_t i = 0; i < fileNames.size(); ++i)
247 DMP::SampledTrajectoryV2 traj;
248 traj.readFromCSVFile(fileNames.at(i));
250 trajs.push_back(traj);
254 ratios.push_back(1.0);
258 ratios.push_back(0.0);
261 dmpPtr->learnFromTrajectories(trajs);
262 dmpPtr->styleParas = dmpPtr->getStyleParasWithRatio(ratios);
276 targetState.resize(dimNames.size());
277 currentState.clear();
278 currentState.resize(dimNames.size());
279 currentDMPState.clear();
280 currentDMPState.resize(dimNames.size());
282 std::vector<double> goalVec = goals;
283 for (
size_t i = 0; i < dimNames.size(); i++)
285 DMP::DMPState currentPos;
289 currentState[i] = currentPos;
290 currentDMPState[i] = currentPos;
292 targetState.push_back(currentPos.pos);
294 if (
rtGetRobot()->getRobotNode(dimNames[i])->isLimitless())
296 double tjv = goalVec[i];
297 double cjv = currentPos.pos;
298 double diff = std::fmod(tjv - cjv, 2 *
M_PI);
299 if (fabs(diff) >
M_PI)
303 diff = -2 *
M_PI - diff;
307 diff = 2 *
M_PI - diff;
318 <<
" current state: qpos: " << currentPos.pos
319 <<
" orig target: " << goals[i] <<
" current goal: " << tjv;
323 dmpPtr->prepareExecution(goalVec, currentDMPState, 1, 1);
324 canVal = timeDuration;
326 isDisturbance =
false;
341 std::stringstream ss;
342 boost::archive::text_oarchive oa{ss};
350 std::stringstream ss;
352 boost::archive::text_iarchive ia{ss};
353 DMP::UMIDMP* newDmpPtr;
355 dmpPtr.reset(newDmpPtr);
356 return dmpPtr->defaultGoal;
363 dmpPtr->setViaPoint(u, viapoint);
369 dmpPtr->setWeights(weights);
375 DMP::DVec2d res = dmpPtr->getWeights();
377 for (
size_t i = 0; i < res.size(); ++i)
379 std::vector<double> cvec;
380 for (
size_t j = 0; j < res[i].size(); ++j)
382 cvec.push_back(res[i][j]);
384 resvec.push_back(cvec);
416 datafields[pair.first] =
new Variant(pair.second);
422 datafields[pair.first +
"_pos"] =
new Variant(pair.second);
427 debugObs->setDebugChannel(
"latestDMPTargetVelocities", datafields);
435 runTask(
"NJointJSDMPController",
440 while (
getState() == eManagedIceObjectStarted)
446 c.waitForCycleDuration();