35 controllerStopRequested =
false;
36 controllerRunFinished =
false;
37 runTask(
"DSRTBimanualControllerTask", [&]
41 while (
getState() == eManagedIceObjectStarted && !controllerStopRequested)
48 c.waitForCycleDuration();
50 controllerRunFinished =
true;
60 controllerStopRequested =
true;
61 while (!controllerRunFinished)
71 cfg = DSRTBimanualControllerConfigPtr::dynamicCast(config);
74 VirtualRobot::RobotNodeSetPtr left_ns =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
75 VirtualRobot::RobotNodeSetPtr right_ns =
rtGetRobot()->getRobotNodeSet(
"RightArm");
77 left_jointNames.clear();
78 right_jointNames.clear();
84 for (
size_t i = 0; i < left_ns->getSize(); ++i)
86 std::string jointName = left_ns->getNode(i)->getName();
87 left_jointNames.push_back(jointName);
92 auto casted_ct = ct->
asA<ControlTarget1DoFActuatorTorque>();
94 left_torque_targets.push_back(casted_ct);
96 const SensorValue1DoFActuatorTorque* torqueSensor = sv->
asA<SensorValue1DoFActuatorTorque>();
97 const SensorValue1DoFActuatorVelocity* velocitySensor = sv->
asA<SensorValue1DoFActuatorVelocity>();
98 const SensorValue1DoFGravityTorque* gravityTorqueSensor = sv->
asA<SensorValue1DoFGravityTorque>();
99 const SensorValue1DoFActuatorPosition* positionSensor = sv->
asA<SensorValue1DoFActuatorPosition>();
104 if (!gravityTorqueSensor)
106 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
109 left_torqueSensors.push_back(torqueSensor);
110 left_gravityTorqueSensors.push_back(gravityTorqueSensor);
111 left_velocitySensors.push_back(velocitySensor);
112 left_positionSensors.push_back(positionSensor);
116 for (
size_t i = 0; i < right_ns->getSize(); ++i)
118 std::string jointName = right_ns->getNode(i)->getName();
119 right_jointNames.push_back(jointName);
124 auto casted_ct = ct->
asA<ControlTarget1DoFActuatorTorque>();
126 right_torque_targets.push_back(casted_ct);
128 const SensorValue1DoFActuatorTorque* torqueSensor = sv->
asA<SensorValue1DoFActuatorTorque>();
129 const SensorValue1DoFActuatorVelocity* velocitySensor = sv->
asA<SensorValue1DoFActuatorVelocity>();
130 const SensorValue1DoFGravityTorque* gravityTorqueSensor = sv->
asA<SensorValue1DoFGravityTorque>();
131 const SensorValue1DoFActuatorPosition* positionSensor = sv->
asA<SensorValue1DoFActuatorPosition>();
136 if (!gravityTorqueSensor)
138 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
141 right_torqueSensors.push_back(torqueSensor);
142 right_gravityTorqueSensors.push_back(gravityTorqueSensor);
143 right_velocitySensors.push_back(velocitySensor);
144 right_positionSensors.push_back(positionSensor);
153 ARMARX_INFO <<
"Initialized " << left_torque_targets.size() <<
" targets for the left arm";
154 ARMARX_INFO <<
"Initialized " << right_torque_targets.size() <<
" targets for the right arm";
156 left_arm_tcp = left_ns->getTCP();
157 right_arm_tcp = right_ns->getTCP();
159 left_sensor_frame = left_ns->getRobot()->getRobotNode(
"ArmL_FT");
160 right_sensor_frame = right_ns->getRobot()->getRobotNode(
"ArmR_FT");
162 left_ik.reset(
new VirtualRobot::DifferentialIK(left_ns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
163 right_ik.reset(
new VirtualRobot::DifferentialIK(right_ns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
167 DSRTBimanualControllerSensorData initSensorData;
169 initSensorData.left_tcpPose = left_arm_tcp->getPoseInRootFrame();
170 initSensorData.currentTime = 0;
173 initSensorData.right_tcpPose = right_arm_tcp->getPoseInRootFrame();
174 initSensorData.currentTime = 0;
178 left_oldPosition = left_arm_tcp->getPositionInRootFrame();
179 left_oldOrientation = left_arm_tcp->getPoseInRootFrame().block<3, 3>(0, 0);
181 right_oldPosition = right_arm_tcp->getPositionInRootFrame();
182 right_oldOrientation = right_arm_tcp->getPoseInRootFrame().block<3, 3>(0, 0);
185 std::vector<float> left_desiredQuaternionVec = cfg->left_desiredQuaternion;
188 std::vector<float> right_desiredQuaternionVec = cfg->right_desiredQuaternion;
191 left_desiredQuaternion.w() = left_desiredQuaternionVec.at(0);
192 left_desiredQuaternion.x() = left_desiredQuaternionVec.at(1);
193 left_desiredQuaternion.y() = left_desiredQuaternionVec.at(2);
194 left_desiredQuaternion.z() = left_desiredQuaternionVec.at(3);
196 right_desiredQuaternion.w() = right_desiredQuaternionVec.at(0);
197 right_desiredQuaternion.x() = right_desiredQuaternionVec.at(1);
198 right_desiredQuaternion.y() = right_desiredQuaternionVec.at(2);
199 right_desiredQuaternion.z() = right_desiredQuaternionVec.at(3);
204 left_jointVelocity_filtered.resize(left_torque_targets.size());
205 left_jointVelocity_filtered.setZero();
206 right_jointVelocity_filtered.resize(left_torque_targets.size());
207 right_jointVelocity_filtered.setZero();
211 for (
size_t i = 0; i < 3; ++i)
218 for (
size_t i = 0; i < 3; ++i)
228 left_desiredTorques_filtered.resize(left_torque_targets.size());
229 left_desiredTorques_filtered.setZero();
230 right_desiredTorques_filtered.resize(right_torque_targets.size());
231 right_desiredTorques_filtered.setZero();
234 left_currentTCPLinearVelocity_filtered.setZero();
235 right_currentTCPLinearVelocity_filtered.setZero();
237 left_currentTCPAngularVelocity_filtered.setZero();
238 right_currentTCPAngularVelocity_filtered.setZero();
240 left_tcpDesiredTorque_filtered.setZero();
241 right_tcpDesiredTorque_filtered.setZero();
247 filterTimeConstant = cfg->filterTimeConstant;
248 posiKp = cfg->posiKp;
250 Damping = cfg->posiDamping;
251 Coupling_stiffness = cfg->couplingStiffness;
252 Coupling_force_limit = cfg->couplingForceLimit;
253 forward_gain = cfg->forwardGain;
254 torqueLimit = cfg->torqueLimit;
255 null_torqueLimit = cfg->NullTorqueLimit;
257 oriDamping = cfg->oriDamping;
258 contactForce = cfg->contactForce;
260 left_oriUp.w() = cfg->left_oriUp[0];
261 left_oriUp.x() = cfg->left_oriUp[1];
262 left_oriUp.y() = cfg->left_oriUp[2];
263 left_oriUp.z() = cfg->left_oriUp[3];
265 left_oriDown.w() = cfg->left_oriDown[0];
266 left_oriDown.x() = cfg->left_oriDown[1];
267 left_oriDown.y() = cfg->left_oriDown[2];
268 left_oriDown.z() = cfg->left_oriDown[3];
270 right_oriUp.w() = cfg->right_oriUp[0];
271 right_oriUp.x() = cfg->right_oriUp[1];
272 right_oriUp.y() = cfg->right_oriUp[2];
273 right_oriUp.z() = cfg->right_oriUp[3];
275 right_oriDown.w() = cfg->right_oriDown[0];
276 right_oriDown.x() = cfg->right_oriDown[1];
277 right_oriDown.y() = cfg->right_oriDown[2];
278 right_oriDown.z() = cfg->right_oriDown[3];
281 guardTargetZUp = cfg->guardTargetZUp;
282 guardTargetZDown = cfg->guardTargetZDown;
283 guardDesiredZ = guardTargetZUp;
284 guard_mounting_correction_z = 0;
286 guardXYHighFrequency = 0;
287 left_force_old.setZero();
288 right_force_old.setZero();
290 left_contactForceZ_correction = 0;
291 right_contactForceZ_correction = 0;
294 std::vector<float> leftarm_qnullspaceVec = cfg->leftarm_qnullspaceVec;
295 std::vector<float> rightarm_qnullspaceVec = cfg->rightarm_qnullspaceVec;
297 left_qnullspace.resize(leftarm_qnullspaceVec.size());
298 right_qnullspace.resize(rightarm_qnullspaceVec.size());
300 for (
size_t i = 0; i < leftarm_qnullspaceVec.size(); ++i)
302 left_qnullspace(i) = leftarm_qnullspaceVec[i];
303 right_qnullspace(i) = rightarm_qnullspaceVec[i];
306 nullspaceKp = cfg->nullspaceKp;
307 nullspaceDamping = cfg->nullspaceDamping;
311 if (cfg->gmmParamsFile ==
"")
313 ARMARX_ERROR <<
"gmm params file cannot be empty string ...";
316 positionErrorTolerance = cfg->positionErrorTolerance;
317 forceFilterCoeff = cfg->forceFilterCoeff;
318 for (
size_t i = 0 ; i < 3; ++i)
320 leftForceOffset[i] = cfg->forceLeftOffset.at(i);
321 rightForceOffset[i] = cfg->forceRightOffset.at(i);
323 isDefaultTarget =
false;
339 Eigen::Vector3f left_force = controllerSensorData.
getReadBuffer().left_force;
340 Eigen::Vector3f right_force = controllerSensorData.
getReadBuffer().right_force;
341 Eigen::Vector3f both_arm_force_ave = - 0.5 * (left_force + right_force);
347 Eigen::Vector3f left_currentTCPPositionInMeter;
348 Eigen::Vector3f right_currentTCPPositionInMeter;
350 left_currentTCPPositionInMeter << left_currentTCPPose(0, 3), left_currentTCPPose(1, 3), left_currentTCPPose(2, 3);
351 right_currentTCPPositionInMeter << right_currentTCPPose(0, 3), right_currentTCPPose(1, 3), right_currentTCPPose(2, 3);
353 left_currentTCPPositionInMeter = 0.001 * left_currentTCPPositionInMeter;
354 right_currentTCPPositionInMeter = 0.001 * right_currentTCPPositionInMeter;
358 float both_arm_height_z_ave = 0.5 * (left_currentTCPPositionInMeter(2) + right_currentTCPPositionInMeter(2));
361 float adaptive_ratio = 1;
362 float force_error_z = 0;
363 float guard_mounting_correction_x = 0;
364 float guard_mounting_correction_y = 0;
367 if (cfg->guardDesiredDirection)
370 force_error_z = both_arm_force_ave(2) - adaptive_ratio * cfg->liftingForce;
373 float diff_norm = (left_force - left_force_old).squaredNorm() + (right_force - right_force_old).squaredNorm();
375 guardXYHighFrequency = cfg->highPassFilterFactor * guardXYHighFrequency + 0.1 * diff_norm;
377 guardXYHighFrequency = (guardXYHighFrequency > 10) ? 10 : guardXYHighFrequency;
379 left_force_old = left_force;
380 right_force_old = right_force;
382 if (fabs(both_arm_height_z_ave - guardTargetZUp) < cfg->mountingDistanceTolerance)
384 guard_mounting_correction_z = (1 - cfg->mountingCorrectionFilterFactor) * guard_mounting_correction_z + cfg->mountingCorrectionFilterFactor * (- 0.1 * (guardXYHighFrequency - 8));
385 guard_mounting_correction_z = deadzone(guard_mounting_correction_z, 0, 0.1);
388 guard_mounting_correction_x = guard_mounting_correction_x - cfg->forceErrorZGain * deadzone(both_arm_force_ave(0), 1, 3);
389 guard_mounting_correction_y = guard_mounting_correction_y - cfg->forceErrorZGain * deadzone(both_arm_force_ave(1), 1, 3);
391 guard_mounting_correction_x = deadzone(guard_mounting_correction_x, 0, 0.1);
392 guard_mounting_correction_y = deadzone(guard_mounting_correction_y, 0, 0.1);
400 adaptive_ratio = (0.5 * (both_arm_height_z_ave - guardTargetZDown) / (guardTargetZUp - guardTargetZDown) + 0.5);
401 force_error_z = both_arm_force_ave(2) - adaptive_ratio * cfg->loweringForce;
407 force_error_z = deadzone(force_error_z, cfg->forceErrorZDisturbance, cfg->forceErrorZThreshold);
408 guardDesiredZ = guardDesiredZ - cfg->forceErrorZGain * (force_error_z);
410 guardDesiredZ = (guardDesiredZ > guardTargetZUp) ? guardTargetZUp : guardDesiredZ;
411 guardDesiredZ = (guardDesiredZ < guardTargetZDown) ? guardTargetZDown : guardDesiredZ;
415 guardDesiredZ = guardTargetZDown;
418 if (!cfg->guardDesiredDirection && guardDesiredZ < 1.5)
420 guard_mounting_correction_y = -0.1;
424 gmmMotionGenerator->updateDesiredVelocity(
425 left_currentTCPPositionInMeter,
426 right_currentTCPPositionInMeter,
427 positionErrorTolerance,
429 guard_mounting_correction_x,
430 guard_mounting_correction_y,
431 guard_mounting_correction_z);
437 Eigen::Vector3f left_tcpDesiredAngularError;
438 Eigen::Vector3f right_tcpDesiredAngularError;
440 left_tcpDesiredAngularError << 0, 0, 0;
441 right_tcpDesiredAngularError << 0, 0, 0;
445 Eigen::Matrix3f left_currentRotMat = left_currentTCPPose.block<3, 3>(0, 0);
446 Eigen::Matrix3f right_currentRotMat = right_currentTCPPose.block<3, 3>(0, 0);
449 float lqratio = (left_currentTCPPositionInMeter(2) - guardTargetZDown) / (guardTargetZUp - guardTargetZDown);
450 float rqratio = (right_currentTCPPositionInMeter(2) - guardTargetZDown) / (guardTargetZUp - guardTargetZDown);
452 lqratio = (lqratio > 1) ? 1 : lqratio;
453 lqratio = (lqratio < 0) ? 0 : lqratio;
454 rqratio = (rqratio > 1) ? 1 : rqratio;
455 rqratio = (rqratio < 0) ? 0 : rqratio;
458 Eigen::Quaternionf left_desiredQuaternion = quatSlerp(lqratio, left_oriDown, left_oriUp);
459 Eigen::Quaternionf right_desiredQuaternion = quatSlerp(rqratio, right_oriDown, right_oriUp);
462 Eigen::Matrix3f left_desiredRotMat = left_desiredQuaternion.normalized().toRotationMatrix();
463 Eigen::Matrix3f right_desiredRotMat = right_desiredQuaternion.normalized().toRotationMatrix();
465 Eigen::Matrix3f left_orientationError = left_currentRotMat * left_desiredRotMat.inverse();
466 Eigen::Matrix3f right_orientationError = right_currentRotMat * right_desiredRotMat.inverse();
471 Eigen::AngleAxisf left_angleAxis(left_diffQuaternion);
472 Eigen::AngleAxisf right_angleAxis(right_diffQuaternion);
474 left_tcpDesiredAngularError = left_angleAxis.angle() * left_angleAxis.axis();
475 right_tcpDesiredAngularError = right_angleAxis.angle() * right_angleAxis.axis();
481 getWriterControlStruct().left_right_distanceInMeter = gmmMotionGenerator->left_right_position_errorInMeter;
489 debugCtrlDataInfo.
getWriteBuffer().guardXYHighFrequency = guardXYHighFrequency;
490 debugCtrlDataInfo.
getWriteBuffer().guard_mounting_correction_x = guard_mounting_correction_x;
491 debugCtrlDataInfo.
getWriteBuffer().guard_mounting_correction_y = guard_mounting_correction_y;
492 debugCtrlDataInfo.
getWriteBuffer().guard_mounting_correction_z = guard_mounting_correction_z;
500 deltaT = timeSinceLastIteration.toSecondsDouble();
503 left_forceInRoot = left_sensor_frame->getPoseInRootFrame().block<3, 3>(0, 0) * (leftForceTorque->
force - leftForceOffset);
504 right_forceInRoot = right_sensor_frame->getPoseInRootFrame().block<3, 3>(0, 0) * (rightForceTorque->
force - rightForceOffset);
505 left_forceInRoot(2) = left_forceInRoot(2) + cfg->leftForceOffsetZ;
506 right_forceInRoot(2) = right_forceInRoot(2) + cfg->rightForceOffsetZ;
509 left_currentTCPPose = left_arm_tcp->getPoseInRootFrame();
510 right_currentTCPPose = right_arm_tcp->getPoseInRootFrame();
512 left_jacobi = left_ik->getJacobianMatrix(left_arm_tcp, VirtualRobot::IKSolver::CartesianSelection::All);
513 right_jacobi = right_ik->getJacobianMatrix(right_arm_tcp, VirtualRobot::IKSolver::CartesianSelection::All);
515 left_qpos.resize(left_positionSensors.size());
516 left_qvel.resize(left_velocitySensors.size());
518 right_qpos.resize(right_positionSensors.size());
519 right_qvel.resize(right_velocitySensors.size());
521 for (
size_t i = 0; i < left_velocitySensors.size(); ++i)
523 left_qpos(i) = left_positionSensors[i]->position;
524 left_qvel(i) = left_velocitySensors[i]->velocity;
526 right_qpos(i) = right_positionSensors[i]->position;
527 right_qvel(i) = right_velocitySensors[i]->velocity;
530 left_tcptwist = left_jacobi * left_qvel;
531 right_tcptwist = right_jacobi * right_qvel;
533 left_tcptwist.head(3) *= 0.001;
534 right_tcptwist.head(3) *= 0.001;
537 double filterFactor = deltaT / (filterTimeConstant + deltaT);
538 left_currentTCPLinearVelocity_filtered = (1 - filterFactor) * left_currentTCPLinearVelocity_filtered + filterFactor * left_tcptwist.head(3);
539 right_currentTCPLinearVelocity_filtered = (1 - filterFactor) * right_currentTCPLinearVelocity_filtered + filterFactor * right_tcptwist.head(3);
540 left_currentTCPAngularVelocity_filtered = (1 - filterFactor) * left_currentTCPAngularVelocity_filtered + left_tcptwist.tail(3);
541 right_currentTCPAngularVelocity_filtered = (1 - filterFactor) * right_currentTCPAngularVelocity_filtered + right_tcptwist.tail(3);
542 left_jointVelocity_filtered = (1 - filterFactor) * left_jointVelocity_filtered + filterFactor * left_qvel;
543 right_jointVelocity_filtered = (1 - filterFactor) * right_jointVelocity_filtered + filterFactor * right_qvel;
546 controllerSensorData.
getWriteBuffer().left_tcpPose = left_currentTCPPose;
547 controllerSensorData.
getWriteBuffer().right_tcpPose = right_currentTCPPose;
548 controllerSensorData.
getWriteBuffer().left_force = left_forceInRoot;
549 controllerSensorData.
getWriteBuffer().right_force = right_forceInRoot;
558 left_DS_force = -(1.2 * left_currentTCPLinearVelocity_filtered - forward_gain *
rtGetControlStruct().left_tcpDesiredLinearVelocity);
559 right_DS_force = -(1.2 * right_currentTCPLinearVelocity_filtered - forward_gain *
rtGetControlStruct().right_tcpDesiredLinearVelocity);
560 for (
int i = 0; i < 3; ++i)
562 left_DS_force(i) = left_DS_force(i) * Damping[i];
563 right_DS_force(i) = right_DS_force(i) * Damping[i];
565 left_DS_force(i) = deadzone(left_DS_force(i), 0.1, 100);
566 right_DS_force(i) = deadzone(right_DS_force(i), 0.1, 100);
571 coupling_force = - Coupling_stiffness *
rtGetControlStruct().left_right_distanceInMeter;
572 float coupling_force_norm = coupling_force.norm();
574 if (coupling_force_norm > Coupling_force_limit)
576 coupling_force = (Coupling_force_limit / coupling_force_norm) * coupling_force;
579 coupling_force(0) = deadzone(coupling_force(0), 0.1, 100);
580 coupling_force(1) = deadzone(coupling_force(1), 0.1, 100);
581 coupling_force(2) = deadzone(coupling_force(2), 0.1, 100);
584 double v_both = left_currentTCPLinearVelocity_filtered.norm() + right_currentTCPLinearVelocity_filtered.norm();
585 float force_contact_switch = 0;
586 float left_height = left_currentTCPPose(2, 3) * 0.001;
587 float right_height = right_currentTCPPose(2, 3) * 0.001;
589 float disTolerance = cfg->contactDistanceTolerance;
590 bool isUp = fabs(left_height - guardTargetZUp) < disTolerance && fabs(right_height - guardTargetZUp) < disTolerance;
591 if (v_both < disTolerance && isUp)
593 force_contact_switch = 1;
595 else if (v_both < 0.05 && isUp)
597 force_contact_switch = (0.05 - v_both) / (0.05 - disTolerance);
599 else if (v_both >= 0.05)
601 force_contact_switch = 0;
605 float left_force_error = force_contact_switch * (-left_forceInRoot(2) - contactForce);
606 float right_force_error = force_contact_switch * (-right_forceInRoot(2) - contactForce);
618 left_force_error = deadzone(left_force_error, 0.5, 2);
619 right_force_error = deadzone(right_force_error, 0.5, 2);
621 left_contactForceZ_correction = left_contactForceZ_correction - forceFilterCoeff * left_force_error;
622 right_contactForceZ_correction = right_contactForceZ_correction - forceFilterCoeff * right_force_error;
624 left_contactForceZ_correction = (left_contactForceZ_correction > 30) ? 30 : left_contactForceZ_correction;
625 right_contactForceZ_correction = (right_contactForceZ_correction > 30) ? 30 : right_contactForceZ_correction;
627 left_contactForceZ_correction = (left_contactForceZ_correction < -30) ? -contactForce : left_contactForceZ_correction;
628 right_contactForceZ_correction = (right_contactForceZ_correction < -30) ? -contactForce : right_contactForceZ_correction;
631 left_tcpDesiredForce = left_DS_force + coupling_force;
632 right_tcpDesiredForce = right_DS_force - coupling_force;
634 left_tcpDesiredForce(2) += force_contact_switch * (contactForce + left_contactForceZ_correction);
635 right_tcpDesiredForce(2) += force_contact_switch * (contactForce + right_contactForceZ_correction);
638 left_tcpDesiredTorque = - oriKp *
rtGetControlStruct().left_tcpDesiredAngularError - oriDamping * left_currentTCPAngularVelocity_filtered;
639 right_tcpDesiredTorque = - oriKp *
rtGetControlStruct().right_tcpDesiredAngularError - oriDamping * right_currentTCPAngularVelocity_filtered;
641 left_tcpDesiredTorque_filtered = (1 - filterFactor) * left_tcpDesiredTorque_filtered + filterFactor * left_tcpDesiredTorque;
642 right_tcpDesiredTorque_filtered = (1 - filterFactor) * right_tcpDesiredTorque_filtered + filterFactor * right_tcpDesiredTorque;
644 left_tcpDesiredWrench.head(3) = 0.001 * left_tcpDesiredForce;
645 left_tcpDesiredWrench.tail(3) = left_tcpDesiredTorque_filtered;
646 right_tcpDesiredWrench.head(3) = 0.001 * right_tcpDesiredForce;
647 right_tcpDesiredWrench.tail(3) = right_tcpDesiredTorque_filtered;
651 left_jtpinv = left_ik->computePseudoInverseJacobianMatrix(left_jacobi.transpose(), lambda);
652 right_jtpinv = right_ik->computePseudoInverseJacobianMatrix(right_jacobi.transpose(), lambda);
654 left_nullqerror = left_qpos - left_qnullspace;
655 right_nullqerror = right_qpos - right_qnullspace;
657 for (
int i = 0; i < left_nullqerror.size(); ++i)
659 if (fabs(left_nullqerror(i)) < 0.09)
661 left_nullqerror(i) = 0;
664 if (fabs(right_nullqerror(i)) < 0.09)
666 right_nullqerror(i) = 0;
670 left_nullspaceTorque = - nullspaceKp * left_nullqerror - nullspaceDamping * left_jointVelocity_filtered;
671 right_nullspaceTorque = - nullspaceKp * right_nullqerror - nullspaceDamping * right_jointVelocity_filtered;
673 left_nullspaceTorque = (I - left_jacobi.transpose() * left_jtpinv) * left_nullspaceTorque;
674 right_nullspaceTorque = (I - right_jacobi.transpose() * right_jtpinv) * right_nullspaceTorque;
676 float left_nulltorque_norm = left_nullspaceTorque.norm();
677 float right_nulltorque_norm = right_nullspaceTorque.norm();
679 if (left_nulltorque_norm > null_torqueLimit)
681 left_nullspaceTorque = (null_torqueLimit / left_nulltorque_norm) * left_nullspaceTorque;
684 if (right_nulltorque_norm > null_torqueLimit)
686 right_nullspaceTorque = (null_torqueLimit / right_nulltorque_norm) * right_nullspaceTorque;
689 left_jointDesiredTorques = left_jacobi.transpose() * left_tcpDesiredWrench + left_nullspaceTorque;
690 right_jointDesiredTorques = right_jacobi.transpose() * right_tcpDesiredWrench + right_nullspaceTorque;
692 right_desiredTorques_filtered = (1 - cfg->TorqueFilterConstant) * right_desiredTorques_filtered + cfg->TorqueFilterConstant * right_jointDesiredTorques;
695 for (
size_t i = 0; i < left_torque_targets.size(); ++i)
697 float desiredTorque = smooth_startup * left_jointDesiredTorques(i);
698 desiredTorque = deadzone(desiredTorque, cfg->desiredTorqueDisturbance, torqueLimit);
699 left_desiredTorques_filtered(i) = (1 - cfg->TorqueFilterConstant) * left_desiredTorques_filtered(i) + cfg->TorqueFilterConstant * desiredTorque;
701 std::string
names = left_jointNames[i] +
"_desiredTorques";
706 if (fabs(left_desiredTorques_filtered(i)) > torqueLimit)
708 left_torque_targets.at(i)->torque = 0;
712 left_torque_targets.at(i)->torque =
713 left_desiredTorques_filtered(i);
715 if (!left_torque_targets.at(i)->isValid())
718 <<
"Torque controller target is invalid - setting to zero! set value: "
719 << left_torque_targets.at(i)->torque;
720 left_torque_targets.at(i)->torque = 0.0f;
724 for (
size_t i = 0; i < right_torque_targets.size(); ++i)
726 float desiredTorque = smooth_startup * right_jointDesiredTorques(i);
727 desiredTorque = deadzone(desiredTorque, cfg->desiredTorqueDisturbance, torqueLimit);
728 right_desiredTorques_filtered(i) = (1 - cfg->TorqueFilterConstant) * right_desiredTorques_filtered(i) + cfg->TorqueFilterConstant * desiredTorque;
730 std::string
names = right_jointNames[i] +
"_desiredTorques";
735 if (fabs(right_desiredTorques_filtered(i)) > torqueLimit)
737 right_torque_targets.at(i)->torque = 0;
741 right_torque_targets.at(i)->torque =
742 right_desiredTorques_filtered(i);
744 if (!right_torque_targets.at(i)->isValid())
747 <<
"Torque controller target is invalid - setting to zero! set value: "
748 << right_torque_targets.at(i)->torque;
749 right_torque_targets.at(i)->torque = 0.0f;
753 smooth_startup = smooth_startup + 0.001 * (1.1 - smooth_startup);
754 smooth_startup = (smooth_startup > 1) ? 1 : smooth_startup;
755 smooth_startup = (smooth_startup < 0) ? 0 : smooth_startup;
759 debugDataInfo.
getWriteBuffer().left_realForce_x = left_forceInRoot(0);
760 debugDataInfo.
getWriteBuffer().left_realForce_y = left_forceInRoot(1);
761 debugDataInfo.
getWriteBuffer().left_realForce_z = left_forceInRoot(2);
762 debugDataInfo.
getWriteBuffer().right_realForce_x = right_forceInRoot(0);
763 debugDataInfo.
getWriteBuffer().right_realForce_y = right_forceInRoot(1);
764 debugDataInfo.
getWriteBuffer().right_realForce_z = right_forceInRoot(2);
766 debugDataInfo.
getWriteBuffer().left_force_error = left_force_error;
767 debugDataInfo.
getWriteBuffer().right_force_error = right_force_error;
770 debugDataInfo.
getWriteBuffer().left_tcpDesiredTorque_x = left_tcpDesiredTorque_filtered(0);
771 debugDataInfo.
getWriteBuffer().left_tcpDesiredTorque_y = left_tcpDesiredTorque_filtered(1);
772 debugDataInfo.
getWriteBuffer().left_tcpDesiredTorque_z = left_tcpDesiredTorque_filtered(2);
773 debugDataInfo.
getWriteBuffer().right_tcpDesiredTorque_x = right_tcpDesiredTorque_filtered(0);
774 debugDataInfo.
getWriteBuffer().right_tcpDesiredTorque_y = right_tcpDesiredTorque_filtered(1);
775 debugDataInfo.
getWriteBuffer().right_tcpDesiredTorque_z = right_tcpDesiredTorque_filtered(2);
800 float DSRTBimanualController::deadzone(
float input,
float disturbance,
float threshold)
821 double cosHalfTheta = q0.w() * q1.w() + q0.x() * q1.x() + q0.y() * q1.y() + q0.z() * q1.z();
825 if (cosHalfTheta < 0)
834 if (fabs(cosHalfTheta) >= 1.0)
839 double halfTheta = acos(cosHalfTheta);
840 double sinHalfTheta =
sqrt(1.0 - cosHalfTheta * cosHalfTheta);
844 if (fabs(sinHalfTheta) < 0.001)
846 result.w() = (1 - t) * q0.w() + t * q1x.w();
847 result.x() = (1 - t) * q0.x() + t * q1x.x();
848 result.y() = (1 - t) * q0.y() + t * q1x.y();
849 result.z() = (1 - t) * q0.z() + t * q1x.z();
854 double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta;
855 double ratioB = sin(t * halfTheta) / sinHalfTheta;
857 result.w() = ratioA * q0.w() + ratioB * q1x.w();
858 result.x() = ratioA * q0.x() + ratioB * q1x.x();
859 result.y() = ratioA * q0.y() + ratioB * q1x.y();
860 result.z() = ratioA * q0.z() + ratioB * q1x.z();
873 datafields[pair.first] =
new Variant(pair.second);
943 debugObs->setDebugChannel(
"DSBimanualControllerOutput", datafields);
949 VirtualRobot::RobotNodeSetPtr rnsLeft =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
950 left_currentTCPPose = rnsLeft->getTCP()->getPoseInRootFrame();
951 VirtualRobot::RobotNodeSetPtr rnsRight =
rtGetRobot()->getRobotNodeSet(
"RightArm");
952 right_currentTCPPose = rnsRight->getTCP()->getPoseInRootFrame();
954 left_qpos = rnsLeft->getJointValuesEigen();
955 right_qpos = rnsRight->getJointValuesEigen();
956 nJointLeft = left_qpos.size();
957 nJointRight = right_qpos.size();
958 left_qvel.setZero(nJointLeft);
959 right_qvel.setZero(nJointRight);
961 left_jacobi = Eigen::MatrixXf::Zero(6, nJointLeft);
962 right_jacobi = Eigen::MatrixXf::Zero(6, nJointRight);
964 left_tcptwist.setZero();
965 right_tcptwist.setZero();
967 left_forceInRoot.setZero();
968 right_forceInRoot.setZero();
970 left_DS_force.setZero();
971 right_DS_force.setZero();
972 coupling_force.setZero();
974 left_tcpDesiredForce.setZero();
975 right_tcpDesiredForce.setZero();
976 left_tcpDesiredTorque.setZero();
977 right_tcpDesiredTorque.setZero();
979 left_tcpDesiredWrench.setZero();
980 right_tcpDesiredWrench.setZero();
984 left_jointDesiredTorques.setZero(nJointLeft);
985 right_jointDesiredTorques.setZero(nJointRight);
986 left_nullqerror.setZero(nJointLeft);
987 right_nullqerror.setZero(nJointRight);
989 left_jtpinv = Eigen::MatrixXf::Zero(6, nJointLeft);
990 right_jtpinv = Eigen::MatrixXf::Zero(6, nJointRight);
1000 isDefaultTarget =
true;