25 #include <VirtualRobot/RobotNodeSet.h>
26 #include <VirtualRobot/Tools/Gravity.h>
27 #include <VirtualRobot/IK/DifferentialIK.h>
34 NJointControllerRegistration<DSRTController>
47 while (
getState() == eManagedIceObjectStarted)
53 c.waitForCycleDuration();
64 const armarx::NJointControllerConfigPtr& config,
67 DSControllerConfigPtr cfg = DSControllerConfigPtr::dynamicCast(config);
69 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
73 for (
size_t i = 0; i < rns->getSize(); ++i)
75 std::string jointName = rns->getNode(i)->getName();
76 jointNames.push_back(jointName);
84 auto casted_ct = ct->
asA<
85 ControlTarget1DoFActuatorTorque>();
87 targets.push_back(casted_ct);
89 const SensorValue1DoFActuatorTorque* torqueSensor =
90 sv->
asA<SensorValue1DoFActuatorTorque>();
91 const SensorValue1DoFActuatorVelocity* velocitySensor =
92 sv->
asA<SensorValue1DoFActuatorVelocity>();
93 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
94 sv->
asA<SensorValue1DoFGravityTorque>();
95 const SensorValue1DoFActuatorPosition* positionSensor =
96 sv->
asA<SensorValue1DoFActuatorPosition>();
101 if (!gravityTorqueSensor)
103 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
106 torqueSensors.push_back(torqueSensor);
107 gravityTorqueSensors.push_back(gravityTorqueSensor);
108 velocitySensors.push_back(velocitySensor);
109 positionSensors.push_back(positionSensor);
111 ARMARX_INFO <<
"Initialized " << targets.size() <<
" targets";
116 ik.reset(
new VirtualRobot::DifferentialIK(
117 rns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
119 DSRTControllerSensorData initSensorData;
120 initSensorData.tcpPose = tcp->getPoseInRootFrame();
121 initSensorData.currentTime = 0;
125 oldPosition = tcp->getPositionInRootFrame();
126 oldOrientation = tcp->getPoseInRootFrame().block<3, 3>(0, 0);
128 std::vector<float> desiredPositionVec = cfg->desiredPosition;
129 for (
size_t i = 0; i < 3; ++i)
131 desiredPosition(i) = desiredPositionVec[i];
135 std::vector<float> desiredQuaternionVec = cfg->desiredQuaternion;
138 desiredQuaternion.x() = desiredQuaternionVec.at(0);
139 desiredQuaternion.y() = desiredQuaternionVec.at(1);
140 desiredQuaternion.z() = desiredQuaternionVec.at(2);
141 desiredQuaternion.w() = desiredQuaternionVec.at(3);
145 for (
size_t i = 0; i < 3; ++i)
150 for (
size_t i = 0; i < 3; ++i)
157 currentTCPLinearVelocity_filtered.setZero();
158 currentTCPAngularVelocity_filtered.setZero();
159 filterTimeConstant = cfg->filterTimeConstant;
160 posiKp = cfg->posiKp;
162 posiDamping = cfg->posiDamping;
163 torqueLimit = cfg->torqueLimit;
165 oriDamping = cfg->oriDamping;
168 std::vector<float> qnullspaceVec = cfg->qnullspaceVec;
170 qnullspace.resize(qnullspaceVec.size());
172 for (
size_t i = 0; i < qnullspaceVec.size(); ++i)
174 qnullspace(i) = qnullspaceVec[i];
177 nullspaceKp = cfg->nullspaceKp;
178 nullspaceDamping = cfg->nullspaceDamping;
182 std::vector<std::string> gmmParamsFiles = cfg->gmmParamsFiles;
183 if (gmmParamsFiles.size() == 0)
188 gmmMotionGenList.clear();
190 for (
size_t i = 0; i < gmmParamsFiles.size(); ++i)
193 sumBelief += gmmMotionGenList[i]->belief;
197 dsAdaptorPtr.reset(
new DSAdaptor(gmmMotionGenList, cfg->dsAdaptorEpsilon));
198 positionErrorTolerance = cfg->positionErrorTolerance;
214 Eigen::Vector3f realVelocity = controllerSensorData.
getReadBuffer().linearVelocity;
216 Eigen::Vector3f currentTCPPositionInMeter;
217 currentTCPPositionInMeter << currentTCPPose(0, 3), currentTCPPose(1, 3),
218 currentTCPPose(2, 3);
219 currentTCPPositionInMeter = 0.001 * currentTCPPositionInMeter;
221 dsAdaptorPtr->updateDesiredVelocity(currentTCPPositionInMeter, positionErrorTolerance);
222 Eigen::Vector3f tcpDesiredLinearVelocity = dsAdaptorPtr->totalDesiredVelocity;
223 dsAdaptorPtr->updateBelief(realVelocity);
226 float vecLen = tcpDesiredLinearVelocity.norm();
230 tcpDesiredLinearVelocity = tcpDesiredLinearVelocity / vecLen * v_max;
233 ARMARX_INFO <<
"tcpDesiredLinearVelocity: " << tcpDesiredLinearVelocity;
235 debugDataInfo.
getWriteBuffer().belief0 = dsAdaptorPtr->task0_belief;
236 debugDataInfo.
getWriteBuffer().belief1 = gmmMotionGenList[0]->belief;
237 debugDataInfo.
getWriteBuffer().belief2 = gmmMotionGenList[1]->belief;
240 Eigen::Vector3f tcpDesiredAngularError;
241 tcpDesiredAngularError << 0, 0, 0;
244 Eigen::Matrix3f desiredOrientation = desiredQuaternion.normalized().toRotationMatrix();
245 Eigen::Matrix3f orientationError = currentOrientation * desiredOrientation.inverse();
247 Eigen::AngleAxisf angleAxis(diffQuaternion);
248 tcpDesiredAngularError = angleAxis.angle() * angleAxis.axis();
260 double deltaT = timeSinceLastIteration.toSecondsDouble();
267 Eigen::MatrixXf jacobi =
268 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
270 Eigen::VectorXf qpos;
271 Eigen::VectorXf qvel;
272 qpos.resize(positionSensors.size());
273 qvel.resize(velocitySensors.size());
275 int jointDim = positionSensors.size();
277 for (
size_t i = 0; i < velocitySensors.size(); ++i)
279 qpos(i) = positionSensors[i]->position;
280 qvel(i) = velocitySensors[i]->velocity;
283 Eigen::VectorXf tcptwist = jacobi * qvel;
285 Eigen::Vector3f currentTCPLinearVelocity;
286 currentTCPLinearVelocity << 0.001 * tcptwist(0), 0.001 * tcptwist(1),
288 double filterFactor = deltaT / (filterTimeConstant + deltaT);
289 currentTCPLinearVelocity_filtered =
290 (1 - filterFactor) * currentTCPLinearVelocity_filtered +
291 filterFactor * currentTCPLinearVelocity;
296 currentTCPLinearVelocity_filtered;
300 Eigen::Vector3f currentTCPAngularVelocity;
301 currentTCPAngularVelocity << tcptwist(3), tcptwist(4), tcptwist(5);
317 Eigen::Vector3f tcpDesiredLinearVelocity =
322 Eigen::Vector3f tcpDesiredForce =
323 -posiDamping * (currentTCPLinearVelocity_filtered - tcpDesiredLinearVelocity);
326 Eigen::Vector3f tcpDesiredTorque =
327 -oriKp * tcpDesiredAngularError - oriDamping * currentTCPAngularVelocity;
330 tcpDesiredWrench << 0.001 * tcpDesiredForce, tcpDesiredTorque;
336 Eigen::MatrixXf jtpinv =
337 ik->computePseudoInverseJacobianMatrix(jacobi.transpose(), lambda);
339 Eigen::VectorXf nullqerror = qpos - qnullspace;
341 for (
int i = 0; i < nullqerror.rows(); ++i)
343 if (fabs(nullqerror(i)) < 0.09)
348 Eigen::VectorXf nullspaceTorque = -nullspaceKp * nullqerror - nullspaceDamping * qvel;
350 Eigen::VectorXf jointDesiredTorques =
351 jacobi.transpose() * tcpDesiredWrench +
352 (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
354 for (
size_t i = 0; i < targets.size(); ++i)
356 float desiredTorque = jointDesiredTorques(i);
358 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
359 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
362 jointDesiredTorques(i);
364 targets.at(i)->torque = desiredTorque;
365 if (!targets.at(i)->isValid())
369 <<
"Torque controller target is invalid - setting to zero! set value: "
370 << targets.at(i)->torque;
371 targets.at(i)->torque = 0.0f;
376 debugDataInfo.
getWriteBuffer().desiredForce_x = tcpDesiredForce(0);
377 debugDataInfo.
getWriteBuffer().desiredForce_y = tcpDesiredForce(1);
378 debugDataInfo.
getWriteBuffer().desiredForce_z = tcpDesiredForce(2);
381 debugDataInfo.
getWriteBuffer().tcpDesiredTorque_x = tcpDesiredTorque(0);
382 debugDataInfo.
getWriteBuffer().tcpDesiredTorque_y = tcpDesiredTorque(1);
383 debugDataInfo.
getWriteBuffer().tcpDesiredTorque_z = tcpDesiredTorque(2);
385 debugDataInfo.
getWriteBuffer().tcpDesiredAngularError_x = tcpDesiredAngularError(0);
386 debugDataInfo.
getWriteBuffer().tcpDesiredAngularError_y = tcpDesiredAngularError(1);
387 debugDataInfo.
getWriteBuffer().tcpDesiredAngularError_z = tcpDesiredAngularError(2);
390 currentTCPAngularVelocity(0);
392 currentTCPAngularVelocity(1);
394 currentTCPAngularVelocity(2);
397 currentTCPLinearVelocity_filtered(0);
399 currentTCPLinearVelocity_filtered(1);
401 currentTCPLinearVelocity_filtered(2);
407 for (
size_t i = 0; i < targets.size(); ++i)
409 targets.at(i)->torque = 0;
424 datafields[pair.first] =
new Variant(pair.second);
445 datafields[
"desiredForce_x"] =
447 datafields[
"desiredForce_y"] =
449 datafields[
"desiredForce_z"] =
452 datafields[
"tcpDesiredTorque_x"] =
454 datafields[
"tcpDesiredTorque_y"] =
456 datafields[
"tcpDesiredTorque_z"] =
459 datafields[
"tcpDesiredAngularError_x"] =
461 datafields[
"tcpDesiredAngularError_y"] =
463 datafields[
"tcpDesiredAngularError_z"] =
466 datafields[
"currentTCPAngularVelocity_x"] =
468 datafields[
"currentTCPAngularVelocity_y"] =
470 datafields[
"currentTCPAngularVelocity_z"] =
474 datafields[
"currentTCPLinearVelocity_x"] =
476 datafields[
"currentTCPLinearVelocity_y"] =
478 datafields[
"currentTCPLinearVelocity_z"] =
485 debugObs->setDebugChannel(
"DSControllerOutput", datafields);