25 #include <VirtualRobot/RobotNodeSet.h>
26 #include <VirtualRobot/Tools/Gravity.h>
27 #include <VirtualRobot/IK/DifferentialIK.h>
34 NJointControllerRegistration<DSRTBimanualController>
41 controllerStopRequested =
false;
42 controllerRunFinished =
false;
43 runTask(
"DSRTBimanualControllerTask",
48 while (
getState() == eManagedIceObjectStarted && !controllerStopRequested)
55 c.waitForCycleDuration();
57 controllerRunFinished =
true;
66 controllerStopRequested =
true;
67 while (!controllerRunFinished)
75 const armarx::NJointControllerConfigPtr& config,
78 cfg = DSRTBimanualControllerConfigPtr::dynamicCast(config);
81 VirtualRobot::RobotNodeSetPtr left_ns =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
82 VirtualRobot::RobotNodeSetPtr right_ns =
rtGetRobot()->getRobotNodeSet(
"RightArm");
84 left_jointNames.clear();
85 right_jointNames.clear();
91 for (
size_t i = 0; i < left_ns->getSize(); ++i)
93 std::string jointName = left_ns->getNode(i)->getName();
94 left_jointNames.push_back(jointName);
102 auto casted_ct = ct->
asA<
103 ControlTarget1DoFActuatorTorque>();
105 left_torque_targets.push_back(casted_ct);
107 const SensorValue1DoFActuatorTorque* torqueSensor =
108 sv->
asA<SensorValue1DoFActuatorTorque>();
109 const SensorValue1DoFActuatorVelocity* velocitySensor =
110 sv->
asA<SensorValue1DoFActuatorVelocity>();
111 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
112 sv->
asA<SensorValue1DoFGravityTorque>();
113 const SensorValue1DoFActuatorPosition* positionSensor =
114 sv->
asA<SensorValue1DoFActuatorPosition>();
119 if (!gravityTorqueSensor)
121 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
124 left_torqueSensors.push_back(torqueSensor);
125 left_gravityTorqueSensors.push_back(gravityTorqueSensor);
126 left_velocitySensors.push_back(velocitySensor);
127 left_positionSensors.push_back(positionSensor);
131 for (
size_t i = 0; i < right_ns->getSize(); ++i)
133 std::string jointName = right_ns->getNode(i)->getName();
134 right_jointNames.push_back(jointName);
142 auto casted_ct = ct->
asA<
143 ControlTarget1DoFActuatorTorque>();
145 right_torque_targets.push_back(casted_ct);
147 const SensorValue1DoFActuatorTorque* torqueSensor =
148 sv->
asA<SensorValue1DoFActuatorTorque>();
149 const SensorValue1DoFActuatorVelocity* velocitySensor =
150 sv->
asA<SensorValue1DoFActuatorVelocity>();
151 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
152 sv->
asA<SensorValue1DoFGravityTorque>();
153 const SensorValue1DoFActuatorPosition* positionSensor =
154 sv->
asA<SensorValue1DoFActuatorPosition>();
159 if (!gravityTorqueSensor)
161 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
164 right_torqueSensors.push_back(torqueSensor);
165 right_gravityTorqueSensors.push_back(gravityTorqueSensor);
166 right_velocitySensors.push_back(velocitySensor);
167 right_positionSensors.push_back(positionSensor);
176 ARMARX_INFO <<
"Initialized " << left_torque_targets.size() <<
" targets for the left arm";
177 ARMARX_INFO <<
"Initialized " << right_torque_targets.size()
178 <<
" targets for the right arm";
180 left_arm_tcp = left_ns->getTCP();
181 right_arm_tcp = right_ns->getTCP();
183 left_sensor_frame = left_ns->getRobot()->getRobotNode(
"ArmL_FT");
184 right_sensor_frame = right_ns->getRobot()->getRobotNode(
"ArmR_FT");
186 left_ik.reset(
new VirtualRobot::DifferentialIK(
187 left_ns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
188 right_ik.reset(
new VirtualRobot::DifferentialIK(
189 right_ns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
193 DSRTBimanualControllerSensorData initSensorData;
195 initSensorData.left_tcpPose = left_arm_tcp->getPoseInRootFrame();
196 initSensorData.currentTime = 0;
199 initSensorData.right_tcpPose = right_arm_tcp->getPoseInRootFrame();
200 initSensorData.currentTime = 0;
204 left_oldPosition = left_arm_tcp->getPositionInRootFrame();
205 left_oldOrientation = left_arm_tcp->getPoseInRootFrame().block<3, 3>(0, 0);
207 right_oldPosition = right_arm_tcp->getPositionInRootFrame();
208 right_oldOrientation = right_arm_tcp->getPoseInRootFrame().block<3, 3>(0, 0);
211 std::vector<float> left_desiredQuaternionVec = cfg->left_desiredQuaternion;
214 std::vector<float> right_desiredQuaternionVec = cfg->right_desiredQuaternion;
217 left_desiredQuaternion.w() = left_desiredQuaternionVec.at(0);
218 left_desiredQuaternion.x() = left_desiredQuaternionVec.at(1);
219 left_desiredQuaternion.y() = left_desiredQuaternionVec.at(2);
220 left_desiredQuaternion.z() = left_desiredQuaternionVec.at(3);
222 right_desiredQuaternion.w() = right_desiredQuaternionVec.at(0);
223 right_desiredQuaternion.x() = right_desiredQuaternionVec.at(1);
224 right_desiredQuaternion.y() = right_desiredQuaternionVec.at(2);
225 right_desiredQuaternion.z() = right_desiredQuaternionVec.at(3);
230 left_jointVelocity_filtered.resize(left_torque_targets.size());
231 left_jointVelocity_filtered.setZero();
232 right_jointVelocity_filtered.resize(left_torque_targets.size());
233 right_jointVelocity_filtered.setZero();
237 for (
size_t i = 0; i < 3; ++i)
243 for (
size_t i = 0; i < 3; ++i)
252 left_desiredTorques_filtered.resize(left_torque_targets.size());
253 left_desiredTorques_filtered.setZero();
254 right_desiredTorques_filtered.resize(right_torque_targets.size());
255 right_desiredTorques_filtered.setZero();
258 left_currentTCPLinearVelocity_filtered.setZero();
259 right_currentTCPLinearVelocity_filtered.setZero();
261 left_currentTCPAngularVelocity_filtered.setZero();
262 right_currentTCPAngularVelocity_filtered.setZero();
264 left_tcpDesiredTorque_filtered.setZero();
265 right_tcpDesiredTorque_filtered.setZero();
271 filterTimeConstant = cfg->filterTimeConstant;
272 posiKp = cfg->posiKp;
274 Damping = cfg->posiDamping;
275 Coupling_stiffness = cfg->couplingStiffness;
276 Coupling_force_limit = cfg->couplingForceLimit;
277 forward_gain = cfg->forwardGain;
278 torqueLimit = cfg->torqueLimit;
279 null_torqueLimit = cfg->NullTorqueLimit;
281 oriDamping = cfg->oriDamping;
282 contactForce = cfg->contactForce;
284 left_oriUp.w() = cfg->left_oriUp[0];
285 left_oriUp.x() = cfg->left_oriUp[1];
286 left_oriUp.y() = cfg->left_oriUp[2];
287 left_oriUp.z() = cfg->left_oriUp[3];
289 left_oriDown.w() = cfg->left_oriDown[0];
290 left_oriDown.x() = cfg->left_oriDown[1];
291 left_oriDown.y() = cfg->left_oriDown[2];
292 left_oriDown.z() = cfg->left_oriDown[3];
294 right_oriUp.w() = cfg->right_oriUp[0];
295 right_oriUp.x() = cfg->right_oriUp[1];
296 right_oriUp.y() = cfg->right_oriUp[2];
297 right_oriUp.z() = cfg->right_oriUp[3];
299 right_oriDown.w() = cfg->right_oriDown[0];
300 right_oriDown.x() = cfg->right_oriDown[1];
301 right_oriDown.y() = cfg->right_oriDown[2];
302 right_oriDown.z() = cfg->right_oriDown[3];
305 guardTargetZUp = cfg->guardTargetZUp;
306 guardTargetZDown = cfg->guardTargetZDown;
307 guardDesiredZ = guardTargetZUp;
308 guard_mounting_correction_z = 0;
310 guardXYHighFrequency = 0;
311 left_force_old.setZero();
312 right_force_old.setZero();
314 left_contactForceZ_correction = 0;
315 right_contactForceZ_correction = 0;
318 std::vector<float> leftarm_qnullspaceVec = cfg->leftarm_qnullspaceVec;
319 std::vector<float> rightarm_qnullspaceVec = cfg->rightarm_qnullspaceVec;
321 left_qnullspace.resize(leftarm_qnullspaceVec.size());
322 right_qnullspace.resize(rightarm_qnullspaceVec.size());
324 for (
size_t i = 0; i < leftarm_qnullspaceVec.size(); ++i)
326 left_qnullspace(i) = leftarm_qnullspaceVec[i];
327 right_qnullspace(i) = rightarm_qnullspaceVec[i];
330 nullspaceKp = cfg->nullspaceKp;
331 nullspaceDamping = cfg->nullspaceDamping;
335 if (cfg->gmmParamsFile ==
"")
337 ARMARX_ERROR <<
"gmm params file cannot be empty string ...";
340 positionErrorTolerance = cfg->positionErrorTolerance;
341 forceFilterCoeff = cfg->forceFilterCoeff;
342 for (
size_t i = 0; i < 3; ++i)
344 leftForceOffset[i] = cfg->forceLeftOffset.at(i);
345 rightForceOffset[i] = cfg->forceRightOffset.at(i);
347 isDefaultTarget =
false;
364 Eigen::Vector3f left_force = controllerSensorData.
getReadBuffer().left_force;
365 Eigen::Vector3f right_force = controllerSensorData.
getReadBuffer().right_force;
366 Eigen::Vector3f both_arm_force_ave =
367 -0.5 * (left_force + right_force);
373 Eigen::Vector3f left_currentTCPPositionInMeter;
374 Eigen::Vector3f right_currentTCPPositionInMeter;
376 left_currentTCPPositionInMeter << left_currentTCPPose(0, 3), left_currentTCPPose(1, 3),
377 left_currentTCPPose(2, 3);
378 right_currentTCPPositionInMeter << right_currentTCPPose(0, 3), right_currentTCPPose(1, 3),
379 right_currentTCPPose(2, 3);
381 left_currentTCPPositionInMeter = 0.001 * left_currentTCPPositionInMeter;
382 right_currentTCPPositionInMeter = 0.001 * right_currentTCPPositionInMeter;
386 float both_arm_height_z_ave =
387 0.5 * (left_currentTCPPositionInMeter(2) + right_currentTCPPositionInMeter(2));
390 float adaptive_ratio = 1;
391 float force_error_z = 0;
392 float guard_mounting_correction_x = 0;
393 float guard_mounting_correction_y = 0;
396 if (cfg->guardDesiredDirection)
399 force_error_z = both_arm_force_ave(2) - adaptive_ratio * cfg->liftingForce;
402 float diff_norm = (left_force - left_force_old).squaredNorm() +
403 (right_force - right_force_old).squaredNorm();
405 guardXYHighFrequency =
406 cfg->highPassFilterFactor * guardXYHighFrequency + 0.1 * diff_norm;
408 guardXYHighFrequency = (guardXYHighFrequency > 10) ? 10 : guardXYHighFrequency;
410 left_force_old = left_force;
411 right_force_old = right_force;
413 if (fabs(both_arm_height_z_ave - guardTargetZUp) < cfg->mountingDistanceTolerance)
415 guard_mounting_correction_z =
416 (1 - cfg->mountingCorrectionFilterFactor) * guard_mounting_correction_z +
417 cfg->mountingCorrectionFilterFactor * (-0.1 * (guardXYHighFrequency - 8));
418 guard_mounting_correction_z = deadzone(guard_mounting_correction_z, 0, 0.1);
421 guard_mounting_correction_x =
422 guard_mounting_correction_x -
423 cfg->forceErrorZGain * deadzone(both_arm_force_ave(0), 1, 3);
424 guard_mounting_correction_y =
425 guard_mounting_correction_y -
426 cfg->forceErrorZGain * deadzone(both_arm_force_ave(1), 1, 3);
428 guard_mounting_correction_x = deadzone(guard_mounting_correction_x, 0, 0.1);
429 guard_mounting_correction_y = deadzone(guard_mounting_correction_y, 0, 0.1);
434 adaptive_ratio = (0.5 * (both_arm_height_z_ave - guardTargetZDown) /
435 (guardTargetZUp - guardTargetZDown) +
437 force_error_z = both_arm_force_ave(2) - adaptive_ratio * cfg->loweringForce;
442 deadzone(force_error_z, cfg->forceErrorZDisturbance, cfg->forceErrorZThreshold);
443 guardDesiredZ = guardDesiredZ - cfg->forceErrorZGain * (force_error_z);
445 guardDesiredZ = (guardDesiredZ > guardTargetZUp) ? guardTargetZUp : guardDesiredZ;
446 guardDesiredZ = (guardDesiredZ < guardTargetZDown) ? guardTargetZDown : guardDesiredZ;
450 guardDesiredZ = guardTargetZDown;
453 if (!cfg->guardDesiredDirection && guardDesiredZ < 1.5)
455 guard_mounting_correction_y = -0.1;
459 gmmMotionGenerator->updateDesiredVelocity(left_currentTCPPositionInMeter,
460 right_currentTCPPositionInMeter,
461 positionErrorTolerance,
463 guard_mounting_correction_x,
464 guard_mounting_correction_y,
465 guard_mounting_correction_z);
471 Eigen::Vector3f left_tcpDesiredAngularError;
472 Eigen::Vector3f right_tcpDesiredAngularError;
474 left_tcpDesiredAngularError << 0, 0, 0;
475 right_tcpDesiredAngularError << 0, 0, 0;
478 Eigen::Matrix3f left_currentRotMat = left_currentTCPPose.block<3, 3>(0, 0);
479 Eigen::Matrix3f right_currentRotMat = right_currentTCPPose.block<3, 3>(0, 0);
482 float lqratio = (left_currentTCPPositionInMeter(2) - guardTargetZDown) /
483 (guardTargetZUp - guardTargetZDown);
484 float rqratio = (right_currentTCPPositionInMeter(2) - guardTargetZDown) /
485 (guardTargetZUp - guardTargetZDown);
487 lqratio = (lqratio > 1) ? 1 : lqratio;
488 lqratio = (lqratio < 0) ? 0 : lqratio;
489 rqratio = (rqratio > 1) ? 1 : rqratio;
490 rqratio = (rqratio < 0) ? 0 : rqratio;
493 Eigen::Quaternionf left_desiredQuaternion = quatSlerp(lqratio, left_oriDown, left_oriUp);
494 Eigen::Quaternionf right_desiredQuaternion = quatSlerp(rqratio, right_oriDown, right_oriUp);
497 Eigen::Matrix3f left_desiredRotMat = left_desiredQuaternion.normalized().toRotationMatrix();
499 right_desiredQuaternion.normalized().toRotationMatrix();
501 Eigen::Matrix3f left_orientationError = left_currentRotMat * left_desiredRotMat.inverse();
503 right_currentRotMat * right_desiredRotMat.inverse();
508 Eigen::AngleAxisf left_angleAxis(left_diffQuaternion);
509 Eigen::AngleAxisf right_angleAxis(right_diffQuaternion);
511 left_tcpDesiredAngularError = left_angleAxis.angle() * left_angleAxis.axis();
512 right_tcpDesiredAngularError = right_angleAxis.angle() * right_angleAxis.axis();
517 gmmMotionGenerator->left_DS_DesiredVelocity;
519 gmmMotionGenerator->right_DS_DesiredVelocity;
521 gmmMotionGenerator->left_right_position_errorInMeter;
529 debugCtrlDataInfo.
getWriteBuffer().guardXYHighFrequency = guardXYHighFrequency;
531 guard_mounting_correction_x;
533 guard_mounting_correction_y;
535 guard_mounting_correction_z;
543 deltaT = timeSinceLastIteration.toSecondsDouble();
546 left_forceInRoot = left_sensor_frame->getPoseInRootFrame().block<3, 3>(0, 0) *
547 (leftForceTorque->
force - leftForceOffset);
548 right_forceInRoot = right_sensor_frame->getPoseInRootFrame().block<3, 3>(0, 0) *
549 (rightForceTorque->
force - rightForceOffset);
550 left_forceInRoot(2) = left_forceInRoot(2) + cfg->leftForceOffsetZ;
551 right_forceInRoot(2) = right_forceInRoot(2) + cfg->rightForceOffsetZ;
554 left_currentTCPPose = left_arm_tcp->getPoseInRootFrame();
555 right_currentTCPPose = right_arm_tcp->getPoseInRootFrame();
557 left_jacobi = left_ik->getJacobianMatrix(left_arm_tcp,
558 VirtualRobot::IKSolver::CartesianSelection::All);
559 right_jacobi = right_ik->getJacobianMatrix(right_arm_tcp,
560 VirtualRobot::IKSolver::CartesianSelection::All);
562 left_qpos.resize(left_positionSensors.size());
563 left_qvel.resize(left_velocitySensors.size());
565 right_qpos.resize(right_positionSensors.size());
566 right_qvel.resize(right_velocitySensors.size());
568 for (
size_t i = 0; i < left_velocitySensors.size(); ++i)
570 left_qpos(i) = left_positionSensors[i]->position;
571 left_qvel(i) = left_velocitySensors[i]->velocity;
573 right_qpos(i) = right_positionSensors[i]->position;
574 right_qvel(i) = right_velocitySensors[i]->velocity;
577 left_tcptwist = left_jacobi * left_qvel;
578 right_tcptwist = right_jacobi * right_qvel;
580 left_tcptwist.head<3>() *= 0.001;
581 right_tcptwist.head<3>() *= 0.001;
584 double filterFactor = deltaT / (filterTimeConstant + deltaT);
585 left_currentTCPLinearVelocity_filtered =
586 (1 - filterFactor) * left_currentTCPLinearVelocity_filtered +
587 filterFactor * left_tcptwist.head<3>();
588 right_currentTCPLinearVelocity_filtered =
589 (1 - filterFactor) * right_currentTCPLinearVelocity_filtered +
590 filterFactor * right_tcptwist.head<3>();
591 left_currentTCPAngularVelocity_filtered =
592 (1 - filterFactor) * left_currentTCPAngularVelocity_filtered + left_tcptwist.tail<3>();
593 right_currentTCPAngularVelocity_filtered =
594 (1 - filterFactor) * right_currentTCPAngularVelocity_filtered + right_tcptwist.tail<3>();
595 left_jointVelocity_filtered =
596 (1 - filterFactor) * left_jointVelocity_filtered + filterFactor * left_qvel;
597 right_jointVelocity_filtered =
598 (1 - filterFactor) * right_jointVelocity_filtered + filterFactor * right_qvel;
601 controllerSensorData.
getWriteBuffer().left_tcpPose = left_currentTCPPose;
602 controllerSensorData.
getWriteBuffer().right_tcpPose = right_currentTCPPose;
603 controllerSensorData.
getWriteBuffer().left_force = left_forceInRoot;
604 controllerSensorData.
getWriteBuffer().right_force = right_forceInRoot;
613 left_DS_force = -(1.2 * left_currentTCPLinearVelocity_filtered -
615 right_DS_force = -(1.2 * right_currentTCPLinearVelocity_filtered -
617 for (
int i = 0; i < 3; ++i)
619 left_DS_force(i) = left_DS_force(i) * Damping[i];
620 right_DS_force(i) = right_DS_force(i) * Damping[i];
622 left_DS_force(i) = deadzone(left_DS_force(i), 0.1, 100);
623 right_DS_force(i) = deadzone(right_DS_force(i), 0.1, 100);
627 coupling_force = -Coupling_stiffness *
rtGetControlStruct().left_right_distanceInMeter;
628 float coupling_force_norm = coupling_force.norm();
630 if (coupling_force_norm > Coupling_force_limit)
632 coupling_force = (Coupling_force_limit / coupling_force_norm) * coupling_force;
635 coupling_force(0) = deadzone(coupling_force(0), 0.1, 100);
636 coupling_force(1) = deadzone(coupling_force(1), 0.1, 100);
637 coupling_force(2) = deadzone(coupling_force(2), 0.1, 100);
640 double v_both = left_currentTCPLinearVelocity_filtered.norm() +
641 right_currentTCPLinearVelocity_filtered.norm();
642 float force_contact_switch = 0;
643 float left_height = left_currentTCPPose(2, 3) * 0.001;
644 float right_height = right_currentTCPPose(2, 3) * 0.001;
646 float disTolerance = cfg->contactDistanceTolerance;
647 bool isUp = fabs(left_height - guardTargetZUp) < disTolerance &&
648 fabs(right_height - guardTargetZUp) < disTolerance;
649 if (v_both < disTolerance && isUp)
651 force_contact_switch = 1;
653 else if (v_both < 0.05 && isUp)
655 force_contact_switch = (0.05 - v_both) / (0.05 - disTolerance);
657 else if (v_both >= 0.05)
659 force_contact_switch = 0;
663 float left_force_error = force_contact_switch * (-left_forceInRoot(2) - contactForce);
664 float right_force_error = force_contact_switch * (-right_forceInRoot(2) - contactForce);
676 left_force_error = deadzone(left_force_error, 0.5, 2);
677 right_force_error = deadzone(right_force_error, 0.5, 2);
679 left_contactForceZ_correction =
680 left_contactForceZ_correction - forceFilterCoeff * left_force_error;
681 right_contactForceZ_correction =
682 right_contactForceZ_correction - forceFilterCoeff * right_force_error;
684 left_contactForceZ_correction =
685 (left_contactForceZ_correction > 30) ? 30 : left_contactForceZ_correction;
686 right_contactForceZ_correction =
687 (right_contactForceZ_correction > 30) ? 30 : right_contactForceZ_correction;
689 left_contactForceZ_correction =
690 (left_contactForceZ_correction < -30) ? -contactForce : left_contactForceZ_correction;
691 right_contactForceZ_correction =
692 (right_contactForceZ_correction < -30) ? -contactForce : right_contactForceZ_correction;
695 left_tcpDesiredForce = left_DS_force + coupling_force;
696 right_tcpDesiredForce = right_DS_force - coupling_force;
698 left_tcpDesiredForce(2) +=
699 force_contact_switch * (contactForce + left_contactForceZ_correction);
700 right_tcpDesiredForce(2) +=
701 force_contact_switch * (contactForce + right_contactForceZ_correction);
705 oriDamping * left_currentTCPAngularVelocity_filtered;
707 oriDamping * right_currentTCPAngularVelocity_filtered;
709 left_tcpDesiredTorque_filtered = (1 - filterFactor) * left_tcpDesiredTorque_filtered +
710 filterFactor * left_tcpDesiredTorque;
711 right_tcpDesiredTorque_filtered = (1 - filterFactor) * right_tcpDesiredTorque_filtered +
712 filterFactor * right_tcpDesiredTorque;
714 left_tcpDesiredWrench.head<3>() = 0.001 * left_tcpDesiredForce;
715 left_tcpDesiredWrench.tail<3>() = left_tcpDesiredTorque_filtered;
716 right_tcpDesiredWrench.head<3>() = 0.001 * right_tcpDesiredForce;
717 right_tcpDesiredWrench.tail<3>() = right_tcpDesiredTorque_filtered;
721 left_jtpinv = left_ik->computePseudoInverseJacobianMatrix(left_jacobi.transpose(), lambda);
723 right_ik->computePseudoInverseJacobianMatrix(right_jacobi.transpose(), lambda);
725 left_nullqerror = left_qpos - left_qnullspace;
726 right_nullqerror = right_qpos - right_qnullspace;
728 for (
int i = 0; i < left_nullqerror.size(); ++i)
730 if (fabs(left_nullqerror(i)) < 0.09)
732 left_nullqerror(i) = 0;
735 if (fabs(right_nullqerror(i)) < 0.09)
737 right_nullqerror(i) = 0;
741 left_nullspaceTorque =
742 -nullspaceKp * left_nullqerror - nullspaceDamping * left_jointVelocity_filtered;
743 right_nullspaceTorque =
744 -nullspaceKp * right_nullqerror - nullspaceDamping * right_jointVelocity_filtered;
746 left_nullspaceTorque = (I - left_jacobi.transpose() * left_jtpinv) * left_nullspaceTorque;
747 right_nullspaceTorque =
748 (I - right_jacobi.transpose() * right_jtpinv) * right_nullspaceTorque;
750 float left_nulltorque_norm = left_nullspaceTorque.norm();
751 float right_nulltorque_norm = right_nullspaceTorque.norm();
753 if (left_nulltorque_norm > null_torqueLimit)
755 left_nullspaceTorque = (null_torqueLimit / left_nulltorque_norm) * left_nullspaceTorque;
758 if (right_nulltorque_norm > null_torqueLimit)
760 right_nullspaceTorque =
761 (null_torqueLimit / right_nulltorque_norm) * right_nullspaceTorque;
764 left_jointDesiredTorques =
765 left_jacobi.transpose() * left_tcpDesiredWrench + left_nullspaceTorque;
766 right_jointDesiredTorques =
767 right_jacobi.transpose() * right_tcpDesiredWrench + right_nullspaceTorque;
769 right_desiredTorques_filtered =
770 (1 - cfg->TorqueFilterConstant) * right_desiredTorques_filtered +
771 cfg->TorqueFilterConstant * right_jointDesiredTorques;
774 for (
size_t i = 0; i < left_torque_targets.size(); ++i)
776 float desiredTorque = smooth_startup * left_jointDesiredTorques(i);
777 desiredTorque = deadzone(desiredTorque, cfg->desiredTorqueDisturbance, torqueLimit);
778 left_desiredTorques_filtered(i) =
779 (1 - cfg->TorqueFilterConstant) * left_desiredTorques_filtered(i) +
780 cfg->TorqueFilterConstant * desiredTorque;
782 std::string
names = left_jointNames[i] +
"_desiredTorques";
787 if (fabs(left_desiredTorques_filtered(i)) > torqueLimit)
789 left_torque_targets.at(i)->torque = 0;
793 left_torque_targets.at(i)->torque =
794 left_desiredTorques_filtered(i);
796 if (!left_torque_targets.at(i)->isValid())
799 <<
"Torque controller target is invalid - setting to zero! set value: "
800 << left_torque_targets.at(i)->torque;
801 left_torque_targets.at(i)->torque = 0.0f;
805 for (
size_t i = 0; i < right_torque_targets.size(); ++i)
807 float desiredTorque = smooth_startup * right_jointDesiredTorques(i);
808 desiredTorque = deadzone(desiredTorque, cfg->desiredTorqueDisturbance, torqueLimit);
809 right_desiredTorques_filtered(i) =
810 (1 - cfg->TorqueFilterConstant) * right_desiredTorques_filtered(i) +
811 cfg->TorqueFilterConstant * desiredTorque;
813 std::string
names = right_jointNames[i] +
"_desiredTorques";
817 right_desiredTorques_filtered(i);
819 if (fabs(right_desiredTorques_filtered(i)) > torqueLimit)
821 right_torque_targets.at(i)->torque = 0;
825 right_torque_targets.at(i)->torque =
826 right_desiredTorques_filtered(i);
828 if (!right_torque_targets.at(i)->isValid())
831 <<
"Torque controller target is invalid - setting to zero! set value: "
832 << right_torque_targets.at(i)->torque;
833 right_torque_targets.at(i)->torque = 0.0f;
837 smooth_startup = smooth_startup + 0.001 * (1.1 - smooth_startup);
838 smooth_startup = (smooth_startup > 1) ? 1 : smooth_startup;
839 smooth_startup = (smooth_startup < 0) ? 0 : smooth_startup;
842 debugDataInfo.
getWriteBuffer().left_realForce_x = left_forceInRoot(0);
843 debugDataInfo.
getWriteBuffer().left_realForce_y = left_forceInRoot(1);
844 debugDataInfo.
getWriteBuffer().left_realForce_z = left_forceInRoot(2);
845 debugDataInfo.
getWriteBuffer().right_realForce_x = right_forceInRoot(0);
846 debugDataInfo.
getWriteBuffer().right_realForce_y = right_forceInRoot(1);
847 debugDataInfo.
getWriteBuffer().right_realForce_z = right_forceInRoot(2);
849 debugDataInfo.
getWriteBuffer().left_force_error = left_force_error;
850 debugDataInfo.
getWriteBuffer().right_force_error = right_force_error;
853 debugDataInfo.
getWriteBuffer().left_tcpDesiredTorque_x = left_tcpDesiredTorque_filtered(0);
854 debugDataInfo.
getWriteBuffer().left_tcpDesiredTorque_y = left_tcpDesiredTorque_filtered(1);
855 debugDataInfo.
getWriteBuffer().left_tcpDesiredTorque_z = left_tcpDesiredTorque_filtered(2);
857 right_tcpDesiredTorque_filtered(0);
859 right_tcpDesiredTorque_filtered(1);
861 right_tcpDesiredTorque_filtered(2);
887 DSRTBimanualController::deadzone(
float input,
float disturbance,
float threshold)
907 DSRTBimanualController::quatSlerp(
double t,
911 double cosHalfTheta = q0.w() * q1.w() + q0.x() * q1.x() + q0.y() * q1.y() + q0.z() * q1.z();
915 if (cosHalfTheta < 0)
924 if (fabs(cosHalfTheta) >= 1.0)
929 double halfTheta = acos(cosHalfTheta);
930 double sinHalfTheta =
sqrt(1.0 - cosHalfTheta * cosHalfTheta);
934 if (fabs(sinHalfTheta) < 0.001)
936 result.w() = (1 - t) * q0.w() + t * q1x.w();
937 result.x() = (1 - t) * q0.x() + t * q1x.x();
938 result.y() = (1 - t) * q0.y() + t * q1x.y();
939 result.z() = (1 - t) * q0.z() + t * q1x.z();
943 double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta;
944 double ratioB = sin(t * halfTheta) / sinHalfTheta;
946 result.w() = ratioA * q0.w() + ratioB * q1x.w();
947 result.x() = ratioA * q0.x() + ratioB * q1x.x();
948 result.y() = ratioA * q0.y() + ratioB * q1x.y();
949 result.z() = ratioA * q0.z() + ratioB * q1x.z();
965 datafields[pair.first] =
new Variant(pair.second);
986 datafields[
"left_tcpDesiredTorque_x"] =
988 datafields[
"left_tcpDesiredTorque_y"] =
990 datafields[
"left_tcpDesiredTorque_z"] =
992 datafields[
"right_tcpDesiredTorque_x"] =
994 datafields[
"right_tcpDesiredTorque_y"] =
996 datafields[
"right_tcpDesiredTorque_z"] =
999 datafields[
"left_realForce_x"] =
1001 datafields[
"left_realForce_y"] =
1003 datafields[
"left_realForce_z"] =
1005 datafields[
"right_realForce_x"] =
1007 datafields[
"right_realForce_y"] =
1009 datafields[
"right_realForce_z"] =
1012 datafields[
"left_force_error"] =
1014 datafields[
"right_force_error"] =
1018 datafields[
"Desired_Guard_Z"] =
1020 datafields[
"Force_Error_Z"] =
1022 datafields[
"guardXYHighFrequency"] =
1024 datafields[
"guard_mounting_correction_x"] =
1026 datafields[
"guard_mounting_correction_y"] =
1028 datafields[
"guard_mounting_correction_z"] =
1054 debugObs->setDebugChannel(
"DSBimanualControllerOutput", datafields);
1060 VirtualRobot::RobotNodeSetPtr rnsLeft =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
1061 left_currentTCPPose = rnsLeft->getTCP()->getPoseInRootFrame();
1062 VirtualRobot::RobotNodeSetPtr rnsRight =
rtGetRobot()->getRobotNodeSet(
"RightArm");
1063 right_currentTCPPose = rnsRight->getTCP()->getPoseInRootFrame();
1065 left_qpos = rnsLeft->getJointValuesEigen();
1066 right_qpos = rnsRight->getJointValuesEigen();
1067 nJointLeft = left_qpos.size();
1068 nJointRight = right_qpos.size();
1069 left_qvel.setZero(nJointLeft);
1070 right_qvel.setZero(nJointRight);
1072 left_jacobi = Eigen::MatrixXf::Zero(6, nJointLeft);
1073 right_jacobi = Eigen::MatrixXf::Zero(6, nJointRight);
1075 left_tcptwist.setZero();
1076 right_tcptwist.setZero();
1078 left_forceInRoot.setZero();
1079 right_forceInRoot.setZero();
1081 left_DS_force.setZero();
1082 right_DS_force.setZero();
1083 coupling_force.setZero();
1085 left_tcpDesiredForce.setZero();
1086 right_tcpDesiredForce.setZero();
1087 left_tcpDesiredTorque.setZero();
1088 right_tcpDesiredTorque.setZero();
1090 left_tcpDesiredWrench.setZero();
1091 right_tcpDesiredWrench.setZero();
1095 left_jointDesiredTorques.setZero(nJointLeft);
1096 right_jointDesiredTorques.setZero(nJointRight);
1097 left_nullqerror.setZero(nJointLeft);
1098 right_nullqerror.setZero(nJointRight);
1100 left_jtpinv = Eigen::MatrixXf::Zero(6, nJointLeft);
1101 right_jtpinv = Eigen::MatrixXf::Zero(6, nJointRight);
1112 isDefaultTarget =
true;