26 const armarx::NJointControllerConfigPtr& config,
30 cfg = NJointPeriodicTSDMPControllerConfigPtr::dynamicCast(config);
32 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
35 for (
size_t i = 0; i < rns->getSize(); ++i)
37 std::string jointName = rns->getNode(i)->getName();
40 targets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
42 const SensorValue1DoFActuatorVelocity* velocitySensor =
43 sv->
asA<SensorValue1DoFActuatorVelocity>();
44 const SensorValue1DoFActuatorPosition* positionSensor =
45 sv->
asA<SensorValue1DoFActuatorPosition>();
47 velocitySensors.push_back(velocitySensor);
48 positionSensors.push_back(positionSensor);
54 nodeSetName = cfg->nodeSetName;
55 ik.reset(
new VirtualRobot::DifferentialIK(
56 rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
64 taskSpaceDMPConfig.
DMPMode =
"Linear";
65 taskSpaceDMPConfig.
DMPStyle =
"Periodic";
80 initData.
targetPose = tcp->getPoseInRootFrame();
82 for (
size_t i = 0; i < 6; ++i)
93 robUnit->getSensorDevice(cfg->forceSensorName)->getSensorValue();
96 forceOffset.setZero();
97 filteredForce.setZero();
99 UserToRTData initUserData;
100 initUserData.targetForce = 0;
101 user2rtData.reinitAllBuffers(initUserData);
103 oriToolDir << 0, 0, 1;
122 if (!rt2CtrlData.updateReadBuffer() || !dmpCtrl)
127 double deltaT = rt2CtrlData.getReadBuffer().deltaT;
128 Eigen::Matrix4f currentPose = rt2CtrlData.getReadBuffer().currentPose;
129 Eigen::VectorXf currentTwist = rt2CtrlData.getReadBuffer().currentTwist;
132 dmpCtrl->flow(deltaT, currentPose, currentTwist);
134 Eigen::VectorXf targetVels = dmpCtrl->getTargetVelocity();
135 Eigen::Matrix4f targetPose = dmpCtrl->getIntegratedPoseMat();
137 debugOutputData.getWriteBuffer().latestTargetVelocities[
"x_vel"] = targetVels(0);
138 debugOutputData.getWriteBuffer().latestTargetVelocities[
"y_vel"] = targetVels(1);
139 debugOutputData.getWriteBuffer().latestTargetVelocities[
"z_vel"] = targetVels(2);
140 debugOutputData.getWriteBuffer().latestTargetVelocities[
"roll_vel"] = targetVels(3);
141 debugOutputData.getWriteBuffer().latestTargetVelocities[
"pitch_vel"] = targetVels(4);
142 debugOutputData.getWriteBuffer().latestTargetVelocities[
"yaw_vel"] = targetVels(5);
143 debugOutputData.getWriteBuffer().currentPose[
"currentPose_x"] = currentPose(0, 3);
144 debugOutputData.getWriteBuffer().currentPose[
"currentPose_y"] = currentPose(1, 3);
145 debugOutputData.getWriteBuffer().currentPose[
"currentPose_z"] = currentPose(2, 3);
146 VirtualRobot::MathTools::Quaternion currentQ =
147 VirtualRobot::MathTools::eigen4f2quat(currentPose);
148 debugOutputData.getWriteBuffer().currentPose[
"currentPose_qw"] = currentQ.w;
149 debugOutputData.getWriteBuffer().currentPose[
"currentPose_qx"] = currentQ.x;
150 debugOutputData.getWriteBuffer().currentPose[
"currentPose_qy"] = currentQ.y;
151 debugOutputData.getWriteBuffer().currentPose[
"currentPose_qz"] = currentQ.z;
152 debugOutputData.getWriteBuffer().currentCanVal = dmpCtrl->debugData.canVal;
153 debugOutputData.getWriteBuffer().mpcFactor = dmpCtrl->debugData.mpcFactor;
154 debugOutputData.getWriteBuffer().error = dmpCtrl->debugData.poseError;
155 debugOutputData.getWriteBuffer().posError = dmpCtrl->debugData.posiError;
156 debugOutputData.getWriteBuffer().oriError = dmpCtrl->debugData.oriError;
157 debugOutputData.getWriteBuffer().deltaT = deltaT;
158 debugOutputData.commitWrite();
169 const IceUtil::Time& timeSinceLastIteration)
171 double deltaT = timeSinceLastIteration.toSecondsDouble();
173 Eigen::Matrix4f currentPose = tcp->getPoseInRootFrame();
174 rt2UserData.getWriteBuffer().currentTcpPose = currentPose;
175 rt2UserData.getWriteBuffer().waitTimeForCalibration += deltaT;
176 rt2UserData.commitWrite();
178 if (firstRun || !dmpRunning)
180 targetPose = currentPose;
181 for (
size_t i = 0; i < targets.size(); ++i)
183 targets.at(i)->velocity = 0.0f;
186 filteredForce.setZero();
188 Eigen::Matrix3f currentHandOri = currentPose.block<3, 3>(0, 0);
189 toolTransform = currentHandOri.transpose();
194 (1 - cfg->forceFilter) * forceOffset + cfg->forceFilter * forceSensor->force;
200 Eigen::MatrixXf jacobi =
201 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
203 Eigen::VectorXf qvel;
204 qvel.resize(velocitySensors.size());
205 for (
size_t i = 0; i < velocitySensors.size(); ++i)
207 qvel(i) = velocitySensors[i]->velocity;
210 Eigen::VectorXf tcptwist = jacobi * qvel;
212 rt2CtrlData.getWriteBuffer().currentPose = currentPose;
213 rt2CtrlData.getWriteBuffer().currentTwist = tcptwist;
214 rt2CtrlData.getWriteBuffer().deltaT = deltaT;
215 rt2CtrlData.getWriteBuffer().currentTime += deltaT;
216 rt2CtrlData.commitWrite();
241 for (
size_t i = 3; i < 6; ++i)
273 float dTf = (
float)deltaT;
274 targetPose.block<3, 1>(0, 3) =
275 targetPose.block<3, 1>(0, 3) + dTf * targetVel.block<3, 1>(0, 0);
276 Eigen::Matrix3f rotVel = VirtualRobot::MathTools::rpy2eigen3f(
277 targetVel(3) * dTf, targetVel(4) * dTf, targetVel(5) * dTf);
278 targetPose.block<3, 3>(0, 0) = rotVel * targetPose.block<3, 3>(0, 0);
284 Eigen::Matrix3f diffMat =
285 targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).inverse();
286 Eigen::Vector3f errorRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
288 Eigen::VectorXf rtTargetVel = targetVel;
289 rtTargetVel.block<3, 1>(0, 0) +=
290 cfg->Kpos * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3));
291 rtTargetVel.block<3, 1>(3, 0) += cfg->Kori * errorRPY;
293 float normLinearVelocity = rtTargetVel.block<3, 1>(0, 0).
norm();
294 if (normLinearVelocity > fabs(cfg->maxLinearVel))
296 rtTargetVel.block<3, 1>(0, 0) =
297 fabs(cfg->maxLinearVel) * rtTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
300 float normAngularVelocity = rtTargetVel.block<3, 1>(3, 0).
norm();
301 if (normAngularVelocity > fabs(cfg->maxAngularVel))
303 rtTargetVel.block<3, 1>(3, 0) =
304 fabs(cfg->maxAngularVel) * rtTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
310 Eigen::VectorXf jnv = Eigen::VectorXf::Zero(tcpController->rns->getSize());
311 if (cfg->avoidJointLimitsKp > 0)
313 jnv += cfg->avoidJointLimitsKp * tcpController->calculateJointLimitAvoidance();
316 Eigen::VectorXf jointTargetVelocities = tcpController->calculate(
317 rtTargetVel, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
318 for (
size_t i = 0; i < targets.size(); ++i)
320 targets.at(i)->velocity = jointTargetVelocities(i);
321 if (!targets.at(i)->isValid())
323 targets.at(i)->velocity = 0.0f;
327 if (fabs(targets.at(i)->velocity) > fabs(cfg->maxJointVel))
329 targets.at(i)->velocity =
330 fabs(cfg->maxJointVel) *
331 (targets.at(i)->velocity / fabs(targets.at(i)->velocity));
398 std::string datafieldName;
399 std::string debugName =
"Periodic";
401 auto values = debugOutputData.getUpToDateReadBuffer().latestTargetVelocities;
402 for (
auto& pair : values)
404 datafieldName = pair.first +
"_" + debugName;
405 datafields[datafieldName] =
new Variant(pair.second);
408 auto currentPose = debugOutputData.getUpToDateReadBuffer().currentPose;
409 for (
auto& pair : currentPose)
411 datafieldName = pair.first +
"_" + debugName;
412 datafields[datafieldName] =
new Variant(pair.second);
415 datafieldName =
"canVal_" + debugName;
416 datafields[datafieldName] =
417 new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
418 datafieldName =
"mpcFactor_" + debugName;
419 datafields[datafieldName] =
new Variant(debugOutputData.getUpToDateReadBuffer().mpcFactor);
420 datafieldName =
"error_" + debugName;
421 datafields[datafieldName] =
new Variant(debugOutputData.getUpToDateReadBuffer().error);
422 datafieldName =
"posError_" + debugName;
423 datafields[datafieldName] =
new Variant(debugOutputData.getUpToDateReadBuffer().posError);
424 datafieldName =
"oriError_" + debugName;
425 datafields[datafieldName] =
new Variant(debugOutputData.getUpToDateReadBuffer().oriError);
426 datafieldName =
"deltaT_" + debugName;
427 datafields[datafieldName] =
new Variant(debugOutputData.getUpToDateReadBuffer().deltaT);
428 datafieldName =
"DMPController_" + debugName;
430 debugObs->setDebugChannel(datafieldName, datafields);