30 NJointControllerRegistration<DSRTController>
43 while (
getState() == eManagedIceObjectStarted)
49 c.waitForCycleDuration();
61 const armarx::NJointControllerConfigPtr& config,
64 DSControllerConfigPtr cfg = DSControllerConfigPtr::dynamicCast(config);
66 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
70 for (
size_t i = 0; i < rns->getSize(); ++i)
72 std::string jointName = rns->getNode(i)->getName();
73 jointNames.push_back(jointName);
81 auto casted_ct = ct->
asA<
82 ControlTarget1DoFActuatorTorque>();
84 targets.push_back(casted_ct);
86 const SensorValue1DoFActuatorTorque* torqueSensor =
87 sv->
asA<SensorValue1DoFActuatorTorque>();
88 const SensorValue1DoFActuatorVelocity* velocitySensor =
89 sv->
asA<SensorValue1DoFActuatorVelocity>();
90 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
91 sv->
asA<SensorValue1DoFGravityTorque>();
92 const SensorValue1DoFActuatorPosition* positionSensor =
93 sv->
asA<SensorValue1DoFActuatorPosition>();
98 if (!gravityTorqueSensor)
100 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
103 torqueSensors.push_back(torqueSensor);
104 gravityTorqueSensors.push_back(gravityTorqueSensor);
105 velocitySensors.push_back(velocitySensor);
106 positionSensors.push_back(positionSensor);
108 ARMARX_INFO <<
"Initialized " << targets.size() <<
" targets";
113 ik.reset(
new VirtualRobot::DifferentialIK(
114 rns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
116 DSRTControllerSensorData initSensorData;
117 initSensorData.tcpPose = tcp->getPoseInRootFrame();
118 initSensorData.currentTime = 0;
122 oldPosition = tcp->getPositionInRootFrame();
123 oldOrientation = tcp->getPoseInRootFrame().block<3, 3>(0, 0);
125 std::vector<float> desiredPositionVec = cfg->desiredPosition;
126 for (
size_t i = 0; i < 3; ++i)
128 desiredPosition(i) = desiredPositionVec[i];
132 std::vector<float> desiredQuaternionVec = cfg->desiredQuaternion;
135 desiredQuaternion.x() = desiredQuaternionVec.at(0);
136 desiredQuaternion.y() = desiredQuaternionVec.at(1);
137 desiredQuaternion.z() = desiredQuaternionVec.at(2);
138 desiredQuaternion.w() = desiredQuaternionVec.at(3);
142 for (
size_t i = 0; i < 3; ++i)
147 for (
size_t i = 0; i < 3; ++i)
154 currentTCPLinearVelocity_filtered.setZero();
155 currentTCPAngularVelocity_filtered.setZero();
156 filterTimeConstant = cfg->filterTimeConstant;
157 posiKp = cfg->posiKp;
159 posiDamping = cfg->posiDamping;
160 torqueLimit = cfg->torqueLimit;
162 oriDamping = cfg->oriDamping;
165 std::vector<float> qnullspaceVec = cfg->qnullspaceVec;
167 qnullspace.resize(qnullspaceVec.size());
169 for (
size_t i = 0; i < qnullspaceVec.size(); ++i)
171 qnullspace(i) = qnullspaceVec[i];
174 nullspaceKp = cfg->nullspaceKp;
175 nullspaceDamping = cfg->nullspaceDamping;
179 std::vector<std::string> gmmParamsFiles = cfg->gmmParamsFiles;
180 if (gmmParamsFiles.size() == 0)
185 gmmMotionGenList.clear();
187 for (
size_t i = 0; i < gmmParamsFiles.size(); ++i)
190 sumBelief += gmmMotionGenList[i]->belief;
194 dsAdaptorPtr.reset(
new DSAdaptor(gmmMotionGenList, cfg->dsAdaptorEpsilon));
195 positionErrorTolerance = cfg->positionErrorTolerance;
212 Eigen::Vector3f realVelocity = controllerSensorData.
getReadBuffer().linearVelocity;
214 Eigen::Vector3f currentTCPPositionInMeter;
215 currentTCPPositionInMeter << currentTCPPose(0, 3), currentTCPPose(1, 3),
216 currentTCPPose(2, 3);
217 currentTCPPositionInMeter = 0.001 * currentTCPPositionInMeter;
219 dsAdaptorPtr->updateDesiredVelocity(currentTCPPositionInMeter, positionErrorTolerance);
220 Eigen::Vector3f tcpDesiredLinearVelocity = dsAdaptorPtr->totalDesiredVelocity;
221 dsAdaptorPtr->updateBelief(realVelocity);
224 float vecLen = tcpDesiredLinearVelocity.norm();
228 tcpDesiredLinearVelocity = tcpDesiredLinearVelocity / vecLen * v_max;
231 ARMARX_INFO <<
"tcpDesiredLinearVelocity: " << tcpDesiredLinearVelocity;
233 debugDataInfo.
getWriteBuffer().belief0 = dsAdaptorPtr->task0_belief;
234 debugDataInfo.
getWriteBuffer().belief1 = gmmMotionGenList[0]->belief;
235 debugDataInfo.
getWriteBuffer().belief2 = gmmMotionGenList[1]->belief;
238 Eigen::Vector3f tcpDesiredAngularError;
239 tcpDesiredAngularError << 0, 0, 0;
242 Eigen::Matrix3f desiredOrientation = desiredQuaternion.normalized().toRotationMatrix();
243 Eigen::Matrix3f orientationError = currentOrientation * desiredOrientation.inverse();
245 Eigen::AngleAxisf angleAxis(diffQuaternion);
246 tcpDesiredAngularError = angleAxis.angle() * angleAxis.axis();
259 double deltaT = timeSinceLastIteration.toSecondsDouble();
266 Eigen::MatrixXf jacobi =
267 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
269 Eigen::VectorXf qpos;
270 Eigen::VectorXf qvel;
271 qpos.resize(positionSensors.size());
272 qvel.resize(velocitySensors.size());
274 int jointDim = positionSensors.size();
276 for (
size_t i = 0; i < velocitySensors.size(); ++i)
278 qpos(i) = positionSensors[i]->position;
279 qvel(i) = velocitySensors[i]->velocity;
282 Eigen::VectorXf tcptwist = jacobi * qvel;
284 Eigen::Vector3f currentTCPLinearVelocity;
285 currentTCPLinearVelocity << 0.001 * tcptwist(0), 0.001 * tcptwist(1),
287 double filterFactor = deltaT / (filterTimeConstant + deltaT);
288 currentTCPLinearVelocity_filtered =
289 (1 - filterFactor) * currentTCPLinearVelocity_filtered +
290 filterFactor * currentTCPLinearVelocity;
295 currentTCPLinearVelocity_filtered;
299 Eigen::Vector3f currentTCPAngularVelocity;
300 currentTCPAngularVelocity << tcptwist(3), tcptwist(4), tcptwist(5);
316 Eigen::Vector3f tcpDesiredLinearVelocity =
321 Eigen::Vector3f tcpDesiredForce =
322 -posiDamping * (currentTCPLinearVelocity_filtered - tcpDesiredLinearVelocity);
325 Eigen::Vector3f tcpDesiredTorque =
326 -oriKp * tcpDesiredAngularError - oriDamping * currentTCPAngularVelocity;
329 tcpDesiredWrench << 0.001 * tcpDesiredForce, tcpDesiredTorque;
335 Eigen::MatrixXf jtpinv =
336 ik->computePseudoInverseJacobianMatrix(jacobi.transpose(), lambda);
338 Eigen::VectorXf nullqerror = qpos - qnullspace;
340 for (
int i = 0; i < nullqerror.rows(); ++i)
342 if (fabs(nullqerror(i)) < 0.09)
347 Eigen::VectorXf nullspaceTorque = -nullspaceKp * nullqerror - nullspaceDamping * qvel;
349 Eigen::VectorXf jointDesiredTorques =
350 jacobi.transpose() * tcpDesiredWrench +
351 (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
353 for (
size_t i = 0; i < targets.size(); ++i)
355 float desiredTorque = jointDesiredTorques(i);
357 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
358 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
361 jointDesiredTorques(i);
363 targets.at(i)->torque = desiredTorque;
364 if (!targets.at(i)->isValid())
368 <<
"Torque controller target is invalid - setting to zero! set value: "
369 << targets.at(i)->torque;
370 targets.at(i)->torque = 0.0f;
375 debugDataInfo.
getWriteBuffer().desiredForce_x = tcpDesiredForce(0);
376 debugDataInfo.
getWriteBuffer().desiredForce_y = tcpDesiredForce(1);
377 debugDataInfo.
getWriteBuffer().desiredForce_z = tcpDesiredForce(2);
380 debugDataInfo.
getWriteBuffer().tcpDesiredTorque_x = tcpDesiredTorque(0);
381 debugDataInfo.
getWriteBuffer().tcpDesiredTorque_y = tcpDesiredTorque(1);
382 debugDataInfo.
getWriteBuffer().tcpDesiredTorque_z = tcpDesiredTorque(2);
384 debugDataInfo.
getWriteBuffer().tcpDesiredAngularError_x = tcpDesiredAngularError(0);
385 debugDataInfo.
getWriteBuffer().tcpDesiredAngularError_y = tcpDesiredAngularError(1);
386 debugDataInfo.
getWriteBuffer().tcpDesiredAngularError_z = tcpDesiredAngularError(2);
389 currentTCPAngularVelocity(0);
391 currentTCPAngularVelocity(1);
393 currentTCPAngularVelocity(2);
396 currentTCPLinearVelocity_filtered(0);
398 currentTCPLinearVelocity_filtered(1);
400 currentTCPLinearVelocity_filtered(2);
406 for (
size_t i = 0; i < targets.size(); ++i)
408 targets.at(i)->torque = 0;
423 datafields[pair.first] =
new Variant(pair.second);
444 datafields[
"desiredForce_x"] =
446 datafields[
"desiredForce_y"] =
448 datafields[
"desiredForce_z"] =
451 datafields[
"tcpDesiredTorque_x"] =
453 datafields[
"tcpDesiredTorque_y"] =
455 datafields[
"tcpDesiredTorque_z"] =
458 datafields[
"tcpDesiredAngularError_x"] =
460 datafields[
"tcpDesiredAngularError_y"] =
462 datafields[
"tcpDesiredAngularError_z"] =
465 datafields[
"currentTCPAngularVelocity_x"] =
467 datafields[
"currentTCPAngularVelocity_y"] =
469 datafields[
"currentTCPAngularVelocity_z"] =
473 datafields[
"currentTCPLinearVelocity_x"] =
475 datafields[
"currentTCPLinearVelocity_y"] =
477 datafields[
"currentTCPLinearVelocity_z"] =
484 debugObs->setDebugChannel(
"DSControllerOutput", datafields);