76 const armarx::NJointControllerConfigPtr& config,
79 cfg = DSJointCarryControllerConfigPtr::dynamicCast(config);
82 VirtualRobot::RobotNodeSetPtr left_ns =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
83 VirtualRobot::RobotNodeSetPtr right_ns =
rtGetRobot()->getRobotNodeSet(
"RightArm");
85 left_jointNames.clear();
86 right_jointNames.clear();
92 for (
size_t i = 0; i < left_ns->getSize(); ++i)
94 std::string jointName = left_ns->getNode(i)->getName();
95 left_jointNames.push_back(jointName);
103 auto casted_ct = ct->
asA<
104 ControlTarget1DoFActuatorTorque>();
106 left_torque_targets.push_back(casted_ct);
108 const SensorValue1DoFActuatorTorque* torqueSensor =
109 sv->
asA<SensorValue1DoFActuatorTorque>();
110 const SensorValue1DoFActuatorVelocity* velocitySensor =
111 sv->
asA<SensorValue1DoFActuatorVelocity>();
112 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
113 sv->
asA<SensorValue1DoFGravityTorque>();
114 const SensorValue1DoFActuatorPosition* positionSensor =
115 sv->
asA<SensorValue1DoFActuatorPosition>();
120 if (!gravityTorqueSensor)
122 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
125 left_torqueSensors.push_back(torqueSensor);
126 left_gravityTorqueSensors.push_back(gravityTorqueSensor);
127 left_velocitySensors.push_back(velocitySensor);
128 left_positionSensors.push_back(positionSensor);
132 for (
size_t i = 0; i < right_ns->getSize(); ++i)
134 std::string jointName = right_ns->getNode(i)->getName();
135 right_jointNames.push_back(jointName);
143 auto casted_ct = ct->
asA<
144 ControlTarget1DoFActuatorTorque>();
146 right_torque_targets.push_back(casted_ct);
148 const SensorValue1DoFActuatorTorque* torqueSensor =
149 sv->
asA<SensorValue1DoFActuatorTorque>();
150 const SensorValue1DoFActuatorVelocity* velocitySensor =
151 sv->
asA<SensorValue1DoFActuatorVelocity>();
152 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
153 sv->
asA<SensorValue1DoFGravityTorque>();
154 const SensorValue1DoFActuatorPosition* positionSensor =
155 sv->
asA<SensorValue1DoFActuatorPosition>();
160 if (!gravityTorqueSensor)
162 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
165 right_torqueSensors.push_back(torqueSensor);
166 right_gravityTorqueSensors.push_back(gravityTorqueSensor);
167 right_velocitySensors.push_back(velocitySensor);
168 right_positionSensors.push_back(positionSensor);
177 ARMARX_INFO <<
"Initialized " << left_torque_targets.size() <<
" targets for the left arm";
178 ARMARX_INFO <<
"Initialized " << right_torque_targets.size()
179 <<
" targets for the right arm";
181 left_arm_tcp = left_ns->getTCP();
182 right_arm_tcp = right_ns->getTCP();
184 left_sensor_frame = left_ns->getRobot()->getRobotNode(
"ArmL_FT");
185 right_sensor_frame = right_ns->getRobot()->getRobotNode(
"ArmR_FT");
187 left_ik.reset(
new VirtualRobot::DifferentialIK(
188 left_ns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
189 right_ik.reset(
new VirtualRobot::DifferentialIK(
190 right_ns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
194 DSJointCarryControllerSensorData initSensorData;
195 initSensorData.left_tcpPose = left_arm_tcp->getPoseInRootFrame();
196 initSensorData.right_tcpPose = right_arm_tcp->getPoseInRootFrame();
197 initSensorData.left_force.setZero();
198 initSensorData.right_force.setZero();
199 initSensorData.currentTime = 0;
200 controllerSensorData.reinitAllBuffers(initSensorData);
202 std::vector<float> left_desiredQuaternionVec = cfg->left_desiredQuaternion;
205 std::vector<float> right_desiredQuaternionVec = cfg->right_desiredQuaternion;
208 left_desiredQuaternion.w() = left_desiredQuaternionVec.at(0);
209 left_desiredQuaternion.x() = left_desiredQuaternionVec.at(1);
210 left_desiredQuaternion.y() = left_desiredQuaternionVec.at(2);
211 left_desiredQuaternion.z() = left_desiredQuaternionVec.at(3);
212 right_desiredQuaternion.w() = right_desiredQuaternionVec.at(0);
213 right_desiredQuaternion.x() = right_desiredQuaternionVec.at(1);
214 right_desiredQuaternion.y() = right_desiredQuaternionVec.at(2);
215 right_desiredQuaternion.z() = right_desiredQuaternionVec.at(3);
219 left_jointVelocity_filtered.resize(left_torque_targets.size());
220 left_jointVelocity_filtered.setZero();
221 right_jointVelocity_filtered.resize(left_torque_targets.size());
222 right_jointVelocity_filtered.setZero();
226 for (
size_t i = 0; i < 3; ++i)
235 Ctrl2InterfaceData initCtrl2InterfaceData;
236 initCtrl2InterfaceData.guardZVel = 0;
237 ctrl2InterfaceData.reinitAllBuffers(initCtrl2InterfaceData);
239 Interface2CtrlData initInterface2CtrlData;
240 initInterface2CtrlData.guardToHandInMeter.setZero();
241 initInterface2CtrlData.guardToHandInMeter[1] = cfg->guardLength / 2;
242 initInterface2CtrlData.guardOriInRobotBase.setIdentity();
243 initInterface2CtrlData.desiredGuardOriInRobotBase.w() = cfg->defaultGuardOri[0];
244 initInterface2CtrlData.desiredGuardOriInRobotBase.x() = cfg->defaultGuardOri[1];
245 initInterface2CtrlData.desiredGuardOriInRobotBase.y() = cfg->defaultGuardOri[2];
246 initInterface2CtrlData.desiredGuardOriInRobotBase.z() = cfg->defaultGuardOri[3];
247 initInterface2CtrlData.guardRotationStiffness << cfg->defaultRotationStiffness[0],
248 cfg->defaultRotationStiffness[1], cfg->defaultRotationStiffness[2];
249 initInterface2CtrlData.guardObsAvoidVel.setZero();
250 interface2CtrlData.reinitAllBuffers(initInterface2CtrlData);
253 left_desiredTorques_filtered.resize(left_torque_targets.size());
254 left_desiredTorques_filtered.setZero();
255 right_desiredTorques_filtered.resize(right_torque_targets.size());
256 right_desiredTorques_filtered.setZero();
259 left_currentTCPLinearVelocity_filtered.setZero();
260 right_currentTCPLinearVelocity_filtered.setZero();
262 left_currentTCPAngularVelocity_filtered.setZero();
263 right_currentTCPAngularVelocity_filtered.setZero();
265 left_tcpDesiredTorque_filtered.setZero();
266 right_tcpDesiredTorque_filtered.setZero();
271 filterTimeConstant = cfg->filterTimeConstant;
272 posiKp = cfg->posiKp;
274 Damping = cfg->posiDamping;
275 torqueLimit = cfg->torqueLimit;
276 null_torqueLimit = cfg->NullTorqueLimit;
278 oriDamping = cfg->oriDamping;
281 left_qnullspace.resize(cfg->leftarm_qnullspaceVec.size());
282 right_qnullspace.resize(cfg->rightarm_qnullspaceVec.size());
283 for (
size_t i = 0; i < cfg->leftarm_qnullspaceVec.size(); ++i)
285 left_qnullspace(i) = cfg->leftarm_qnullspaceVec[i];
286 right_qnullspace(i) = cfg->rightarm_qnullspaceVec[i];
288 nullspaceKp = cfg->nullspaceKp;
289 nullspaceDamping = cfg->nullspaceDamping;
293 if (cfg->gmmParamsFile ==
"")
295 ARMARX_ERROR <<
"gmm params file cannot be empty string ...";
305 if (!controllerSensorData.updateReadBuffer())
311 Eigen::Matrix4f left_currentTCPPose = controllerSensorData.getReadBuffer().left_tcpPose;
312 Eigen::Matrix4f right_currentTCPPose = controllerSensorData.getReadBuffer().right_tcpPose;
314 Eigen::Vector3f left_currentTCPPositionInMeter;
315 Eigen::Vector3f right_currentTCPPositionInMeter;
316 left_currentTCPPositionInMeter << left_currentTCPPose(0, 3), left_currentTCPPose(1, 3),
317 left_currentTCPPose(2, 3);
318 right_currentTCPPositionInMeter << right_currentTCPPose(0, 3), right_currentTCPPose(1, 3),
319 right_currentTCPPose(2, 3);
320 left_currentTCPPositionInMeter = 0.001 * left_currentTCPPositionInMeter;
321 right_currentTCPPositionInMeter = 0.001 * right_currentTCPPositionInMeter;
323 interface2CtrlData.updateReadBuffer();
325 interface2CtrlData.getReadBuffer().guardOriInRobotBase;
327 interface2CtrlData.getReadBuffer().desiredGuardOriInRobotBase;
328 Eigen::Vector3f guardToHandInMeter = interface2CtrlData.getReadBuffer().guardToHandInMeter;
329 Eigen::Vector3f guardRotationStiffness =
330 interface2CtrlData.getReadBuffer().guardRotationStiffness;
331 Eigen::Vector3f guardModulatedVel = interface2CtrlData.getReadBuffer().guardObsAvoidVel;
333 Eigen::Vector3f left_to_right =
334 right_currentTCPPositionInMeter - left_currentTCPPositionInMeter;
335 left_to_right.normalize();
337 Eigen::Vector3f guard_currentPosition;
338 guard_currentPosition =
339 (left_currentTCPPositionInMeter + right_currentTCPPositionInMeter) / 2 +
341 gmmMotionGenerator->updateDesiredVelocity(guard_currentPosition,
342 cfg->positionErrorTolerance);
343 Eigen::Vector3f guardDesiredLinearVelocity = gmmMotionGenerator->guard_desiredVelocity;
346 ctrl2InterfaceData.getWriteBuffer().guardZVel = guardDesiredLinearVelocity[2];
347 ctrl2InterfaceData.commitWrite();
349 guardDesiredLinearVelocity[2] = guardDesiredLinearVelocity[2] + guardModulatedVel[2];
352 if (guard_desiredOrientation.coeffs().dot(guard_currentOrientation.coeffs()) < 0.0)
354 guard_currentOrientation.coeffs() << -guard_currentOrientation.coeffs();
356 Eigen::Quaternionf errorOri = guard_currentOrientation * guard_desiredOrientation.inverse();
357 Eigen::AngleAxisf err_axang(errorOri);
358 Eigen::Vector3f guard_angular_error = err_axang.axis() * err_axang.angle();
359 Eigen::Vector3f guard_desired_angular_vel =
360 -1 * guardRotationStiffness.cwiseProduct(guard_angular_error);
363 Eigen::Vector3f guard_to_left = left_currentTCPPositionInMeter - guard_currentPosition;
364 Eigen::Vector3f leftOriGenLinearVelocity = guard_desired_angular_vel.cross(guard_to_left);
365 leftOriGenLinearVelocity -= leftOriGenLinearVelocity.dot(left_to_right) * left_to_right;
366 Eigen::Vector3f leftDesiredLinearVelocity =
367 leftOriGenLinearVelocity + guardDesiredLinearVelocity;
369 if (leftDesiredLinearVelocity.norm() > cfg->handVelLimit)
371 leftDesiredLinearVelocity =
372 cfg->handVelLimit * leftDesiredLinearVelocity / leftDesiredLinearVelocity.norm();
375 Eigen::Vector3f guard_to_right = right_currentTCPPositionInMeter - guard_currentPosition;
376 Eigen::Vector3f rightOriGenLinearVelocity = guard_desired_angular_vel.cross(guard_to_right);
377 rightOriGenLinearVelocity -= rightOriGenLinearVelocity.dot(left_to_right) * left_to_right;
378 Eigen::Vector3f rightDesiredLinearVelocity =
379 rightOriGenLinearVelocity + guardDesiredLinearVelocity;
381 if (rightDesiredLinearVelocity.norm() > cfg->handVelLimit)
383 rightDesiredLinearVelocity =
384 cfg->handVelLimit * rightDesiredLinearVelocity / rightDesiredLinearVelocity.norm();
388 Eigen::Matrix3f left_currentRotMat = left_currentTCPPose.block<3, 3>(0, 0);
389 Eigen::Matrix3f right_currentRotMat = right_currentTCPPose.block<3, 3>(0, 0);
390 Eigen::Matrix3f left_desiredRotMat = left_desiredQuaternion.normalized().toRotationMatrix();
391 Eigen::Matrix3f right_desiredRotMat =
392 right_desiredQuaternion.normalized().toRotationMatrix();
393 Eigen::Matrix3f left_orientationError = left_currentRotMat * left_desiredRotMat.inverse();
394 Eigen::Matrix3f right_orientationError =
395 right_currentRotMat * right_desiredRotMat.inverse();
398 Eigen::AngleAxisf left_angleAxis(left_diffQuaternion);
399 Eigen::AngleAxisf right_angleAxis(right_diffQuaternion);
400 Eigen::Vector3f left_tcpDesiredAngularError =
401 left_angleAxis.angle() * left_angleAxis.axis();
402 Eigen::Vector3f right_tcpDesiredAngularError =
403 right_angleAxis.angle() * right_angleAxis.axis();
413 debugCtrlDataInfo.getWriteBuffer().leftDesiredLinearVelocity = leftDesiredLinearVelocity;
414 debugCtrlDataInfo.getWriteBuffer().rightDesiredLinearVelocity = rightDesiredLinearVelocity;
415 debugCtrlDataInfo.commitWrite();
420 const IceUtil::Time& timeSinceLastIteration)
423 double deltaT = timeSinceLastIteration.toSecondsDouble();
425 Eigen::Matrix4f leftSensorFrame = left_sensor_frame->getPoseInRootFrame();
426 Eigen::Matrix4f rightSensorFrame = right_sensor_frame->getPoseInRootFrame();
427 Eigen::Vector3f left_forceInRoot =
428 leftSensorFrame.block<3, 3>(0, 0) * (leftForceTorque->force);
429 Eigen::Vector3f right_forceInRoot =
430 rightSensorFrame.block<3, 3>(0, 0) * (rightForceTorque->force);
431 left_forceInRoot(2) = left_forceInRoot(2);
432 right_forceInRoot(2) = right_forceInRoot(2);
433 Eigen::Matrix4f left_currentTCPPose = left_arm_tcp->getPoseInRootFrame();
434 Eigen::Matrix4f right_currentTCPPose = right_arm_tcp->getPoseInRootFrame();
437 Eigen::MatrixXf left_jacobi = left_ik->getJacobianMatrix(
438 left_arm_tcp, VirtualRobot::IKSolver::CartesianSelection::All);
439 Eigen::MatrixXf right_jacobi = right_ik->getJacobianMatrix(
440 right_arm_tcp, VirtualRobot::IKSolver::CartesianSelection::All);
442 Eigen::VectorXf left_qpos;
443 Eigen::VectorXf left_qvel;
445 Eigen::VectorXf right_qpos;
446 Eigen::VectorXf right_qvel;
448 left_qpos.resize(left_positionSensors.size());
449 left_qvel.resize(left_velocitySensors.size());
451 right_qpos.resize(right_positionSensors.size());
452 right_qvel.resize(right_velocitySensors.size());
454 int jointDim = left_positionSensors.size();
456 for (
size_t i = 0; i < left_velocitySensors.size(); ++i)
458 left_qpos(i) = left_positionSensors[i]->position;
459 left_qvel(i) = left_velocitySensors[i]->velocity;
461 right_qpos(i) = right_positionSensors[i]->position;
462 right_qvel(i) = right_velocitySensors[i]->velocity;
465 Eigen::VectorXf left_tcptwist = left_jacobi * left_qvel;
466 Eigen::VectorXf right_tcptwist = right_jacobi * right_qvel;
468 Eigen::Vector3f left_currentTCPLinearVelocity;
469 Eigen::Vector3f right_currentTCPLinearVelocity;
470 Eigen::Vector3f left_currentTCPAngularVelocity;
471 Eigen::Vector3f right_currentTCPAngularVelocity;
472 left_currentTCPLinearVelocity << 0.001 * left_tcptwist(0), 0.001 * left_tcptwist(1),
473 0.001 * left_tcptwist(2);
474 right_currentTCPLinearVelocity << 0.001 * right_tcptwist(0), 0.001 * right_tcptwist(1),
475 0.001 * right_tcptwist(2);
476 left_currentTCPAngularVelocity << left_tcptwist(3), left_tcptwist(4), left_tcptwist(5);
477 right_currentTCPAngularVelocity << right_tcptwist(3), right_tcptwist(4), right_tcptwist(5);
478 double filterFactor = deltaT / (filterTimeConstant + deltaT);
479 left_currentTCPLinearVelocity_filtered =
480 (1 - filterFactor) * left_currentTCPLinearVelocity_filtered +
481 filterFactor * left_currentTCPLinearVelocity;
482 right_currentTCPLinearVelocity_filtered =
483 (1 - filterFactor) * right_currentTCPLinearVelocity_filtered +
484 filterFactor * right_currentTCPLinearVelocity;
485 left_currentTCPAngularVelocity_filtered =
486 (1 - filterFactor) * left_currentTCPAngularVelocity_filtered +
487 left_currentTCPAngularVelocity;
488 right_currentTCPAngularVelocity_filtered =
489 (1 - filterFactor) * right_currentTCPAngularVelocity_filtered +
490 right_currentTCPAngularVelocity;
491 left_jointVelocity_filtered =
492 (1 - filterFactor) * left_jointVelocity_filtered + filterFactor * left_qvel;
493 right_jointVelocity_filtered =
494 (1 - filterFactor) * right_jointVelocity_filtered + filterFactor * right_qvel;
496 controllerSensorData.getWriteBuffer().left_tcpPose = left_currentTCPPose;
497 controllerSensorData.getWriteBuffer().right_tcpPose = right_currentTCPPose;
498 controllerSensorData.getWriteBuffer().left_force = left_forceInRoot;
499 controllerSensorData.getWriteBuffer().right_force = right_forceInRoot;
500 controllerSensorData.getWriteBuffer().currentTime += deltaT;
501 controllerSensorData.commitWrite();
504 Eigen::Vector3f leftDesiredLinearVelocity =
rtGetControlStruct().leftDesiredLinearVelocity;
505 Eigen::Vector3f rightDesiredLinearVelocity =
507 Eigen::Vector3f left_tcpDesiredAngularError =
rtGetControlStruct().leftDesiredAngularError;
508 Eigen::Vector3f right_tcpDesiredAngularError =
512 Eigen::Vector3f left_DS_force =
513 -(left_currentTCPLinearVelocity_filtered - leftDesiredLinearVelocity);
514 Eigen::Vector3f right_DS_force =
515 -(right_currentTCPLinearVelocity_filtered - rightDesiredLinearVelocity);
516 for (
int i = 0; i < 3; ++i)
518 left_DS_force(i) = left_DS_force(i) * Damping[i];
519 right_DS_force(i) = right_DS_force(i) * Damping[i];
520 left_DS_force(i) = deadzone(left_DS_force(i), 0.1, 100);
521 right_DS_force(i) = deadzone(right_DS_force(i), 0.1, 100);
524 Eigen::Vector3f left_tcpDesiredTorque =
525 -oriKp * left_tcpDesiredAngularError -
526 oriDamping * left_currentTCPAngularVelocity_filtered;
527 Eigen::Vector3f right_tcpDesiredTorque =
528 -oriKp * right_tcpDesiredAngularError -
529 oriDamping * right_currentTCPAngularVelocity_filtered;
531 left_tcpDesiredTorque_filtered = (1 - filterFactor) * left_tcpDesiredTorque_filtered +
532 filterFactor * left_tcpDesiredTorque;
533 right_tcpDesiredTorque_filtered = (1 - filterFactor) * right_tcpDesiredTorque_filtered +
534 filterFactor * right_tcpDesiredTorque;
540 left_tcpDesiredWrench << 0.001 * left_DS_force, left_tcpDesiredTorque_filtered;
541 right_tcpDesiredWrench << 0.001 * right_DS_force, right_tcpDesiredTorque_filtered;
548 Eigen::MatrixXf I = Eigen::MatrixXf::Identity(jointDim, jointDim);
550 Eigen::MatrixXf left_jtpinv =
551 left_ik->computePseudoInverseJacobianMatrix(left_jacobi.transpose(), lambda);
552 Eigen::MatrixXf right_jtpinv =
553 right_ik->computePseudoInverseJacobianMatrix(right_jacobi.transpose(), lambda);
554 Eigen::VectorXf left_nullqerror = left_qpos - left_qnullspace;
555 Eigen::VectorXf right_nullqerror = right_qpos - right_qnullspace;
557 for (
int i = 0; i < left_nullqerror.size(); ++i)
559 if (fabs(left_nullqerror(i)) < 0.09)
561 left_nullqerror(i) = 0;
564 if (fabs(right_nullqerror(i)) < 0.09)
566 right_nullqerror(i) = 0;
570 Eigen::VectorXf left_nullspaceTorque =
571 -nullspaceKp * left_nullqerror - nullspaceDamping * left_jointVelocity_filtered;
572 Eigen::VectorXf right_nullspaceTorque =
573 -nullspaceKp * right_nullqerror - nullspaceDamping * right_jointVelocity_filtered;
574 Eigen::VectorXf left_projectedNullTorque =
575 (I - left_jacobi.transpose() * left_jtpinv) * left_nullspaceTorque;
576 Eigen::VectorXf right_projectedNullTorque =
577 (I - right_jacobi.transpose() * right_jtpinv) * right_nullspaceTorque;
578 float left_nulltorque_norm = left_projectedNullTorque.norm();
579 float right_nulltorque_norm = right_projectedNullTorque.norm();
580 if (left_nulltorque_norm > null_torqueLimit)
582 left_projectedNullTorque =
583 (null_torqueLimit / left_nulltorque_norm) * left_projectedNullTorque;
585 if (right_nulltorque_norm > null_torqueLimit)
587 right_projectedNullTorque =
588 (null_torqueLimit / right_nulltorque_norm) * right_projectedNullTorque;
591 Eigen::VectorXf left_jointDesiredTorques =
592 left_jacobi.transpose() * left_tcpDesiredWrench + left_projectedNullTorque;
593 Eigen::VectorXf right_jointDesiredTorques =
594 right_jacobi.transpose() * right_tcpDesiredWrench + right_projectedNullTorque;
595 for (
size_t i = 0; i < left_torque_targets.size(); ++i)
597 float desiredTorque = smooth_startup * left_jointDesiredTorques(i);
598 desiredTorque = deadzone(desiredTorque, cfg->desiredTorqueDisturbance, torqueLimit);
599 left_desiredTorques_filtered(i) =
600 (1 - cfg->TorqueFilterConstant) * left_desiredTorques_filtered(i) +
601 cfg->TorqueFilterConstant * desiredTorque;
603 std::string names = left_jointNames[i] +
"_desiredTorques";
604 debugDataInfo.getWriteBuffer().desired_torques[names] = desiredTorque;
605 names = names +
"_filtered";
606 debugDataInfo.getWriteBuffer().desired_torques[names] = left_desiredTorques_filtered(i);
608 if (fabs(left_desiredTorques_filtered(i)) > torqueLimit)
610 left_torque_targets.at(i)->torque = 0;
614 left_torque_targets.at(i)->torque =
615 left_desiredTorques_filtered(i);
619 for (
size_t i = 0; i < right_torque_targets.size(); ++i)
621 float desiredTorque = smooth_startup * right_jointDesiredTorques(i);
622 desiredTorque = deadzone(desiredTorque, cfg->desiredTorqueDisturbance, torqueLimit);
623 right_desiredTorques_filtered(i) =
624 (1 - cfg->TorqueFilterConstant) * right_desiredTorques_filtered(i) +
625 cfg->TorqueFilterConstant * desiredTorque;
627 std::string names = right_jointNames[i] +
"_desiredTorques";
628 debugDataInfo.getWriteBuffer().desired_torques[names] = desiredTorque;
629 names = names +
"_filtered";
630 debugDataInfo.getWriteBuffer().desired_torques[names] =
631 right_desiredTorques_filtered(i);
633 if (fabs(right_desiredTorques_filtered(i)) > torqueLimit)
635 right_torque_targets.at(i)->torque = 0;
639 right_torque_targets.at(i)->torque =
640 right_desiredTorques_filtered(i);
644 smooth_startup = smooth_startup + 0.001 * (1.1 - smooth_startup);
645 smooth_startup = (smooth_startup > 1) ? 1 : smooth_startup;
646 smooth_startup = (smooth_startup < 0) ? 0 : smooth_startup;
648 debugDataInfo.commitWrite();