8 NJointControllerRegistration<NJointBimanualForceMPController>
12 const RobotUnitPtr& robUnit,
13 const armarx::NJointControllerConfigPtr& config,
17 cfg = NJointBimanualForceMPControllerConfigPtr::dynamicCast(config);
19 VirtualRobot::RobotNodeSetPtr lrns =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
20 for (
size_t i = 0; i < lrns->getSize(); ++i)
22 std::string jointName = lrns->getNode(i)->getName();
25 leftTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
26 const SensorValue1DoFActuatorVelocity* velocitySensor =
27 sv->
asA<SensorValue1DoFActuatorVelocity>();
28 const SensorValue1DoFActuatorPosition* positionSensor =
29 sv->
asA<SensorValue1DoFActuatorPosition>();
33 ARMARX_WARNING <<
"No velocity sensor available for " << jointName;
37 ARMARX_WARNING <<
"No position sensor available for " << jointName;
40 leftVelocitySensors.push_back(velocitySensor);
41 leftPositionSensors.push_back(positionSensor);
44 VirtualRobot::RobotNodeSetPtr rrns =
rtGetRobot()->getRobotNodeSet(
"RightArm");
45 for (
size_t i = 0; i < rrns->getSize(); ++i)
47 std::string jointName = rrns->getNode(i)->getName();
50 rightTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
51 const SensorValue1DoFActuatorVelocity* velocitySensor =
52 sv->
asA<SensorValue1DoFActuatorVelocity>();
53 const SensorValue1DoFActuatorPosition* positionSensor =
54 sv->
asA<SensorValue1DoFActuatorPosition>();
58 ARMARX_WARNING <<
"No velocity sensor available for " << jointName;
62 ARMARX_WARNING <<
"No position sensor available for " << jointName;
65 rightVelocitySensors.push_back(velocitySensor);
66 rightPositionSensors.push_back(positionSensor);
68 const SensorValueBase* svlf = robUnit->getSensorDevice(
"FT L")->getSensorValue();
70 const SensorValueBase* svrf = robUnit->getSensorDevice(
"FT R")->getSensorValue();
73 leftIK.reset(
new VirtualRobot::DifferentialIK(
74 lrns, lrns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
75 rightIK.reset(
new VirtualRobot::DifferentialIK(
76 rrns, rrns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
78 leftTCP = lrns->getTCP();
79 rightTCP = rrns->getTCP();
93 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
94 taskSpaceDMPConfig.
DMPStyle = cfg->dmpStyle;
110 NJointBimanualForceMPControllerSensorData initSensorData;
111 initSensorData.leftPoseInRootFrame = leftTCP->getPoseInRootFrame();
112 initSensorData.leftTwistInRootFrame.setZero();
113 initSensorData.rightPoseInRootFrame = rightTCP->getPoseInRootFrame();
114 initSensorData.rightTwistInRootFrame.setZero();
115 initSensorData.leftForceInRootFrame.setZero();
116 initSensorData.rightForceInRootFrame.setZero();
125 Kp_LinearVel = cfg->Kp_LinearVel;
126 Kp_AngularVel = cfg->Kp_AngularVel;
127 Kd_LinearVel = cfg->Kd_LinearVel;
128 Kd_AngularVel = cfg->Kd_AngularVel;
134 leftFilteredValue.setZero();
135 rightFilteredValue.setZero();
137 for (
size_t i = 0; i < 3; ++i)
139 leftForceOffset(i) = cfg->leftForceOffset.at(i);
141 for (
size_t i = 0; i < 3; ++i)
143 rightForceOffset(i) = cfg->rightForceOffset.at(i);
147 targetSupportForce = cfg->targetSupportForce;
149 NJointBimanualForceMPControllerInterfaceData initInterfaceData;
150 initInterfaceData.leftTcpPoseInRootFrame = leftTCP->getPoseInRootFrame();
151 initInterfaceData.rightTcpPoseInRootFrame = rightTCP->getPoseInRootFrame();
158 return "NJointBimanualForceMPController";
164 if (!controllerSensorData.
updateReadBuffer() || !leftDMPController || !rightDMPController)
173 Eigen::Vector3f leftForce = controllerSensorData.
getReadBuffer().leftForceInRootFrame;
174 Eigen::Vector3f rightForce = controllerSensorData.
getReadBuffer().rightForceInRootFrame;
176 float forceOnHands = (leftForce + rightForce)(2);
179 cfg->forceP * (targetSupportForce + forceOnHands) + I_decay * cfg->forceI * forceIterm;
181 forceIterm += targetSupportForce - forceOnHands;
183 canVal = canVal + forceSign * xvel * deltaT;
187 if (canVal > cfg->timeDuration)
189 canVal = cfg->timeDuration;
193 leftDMPController->canVal = canVal;
194 rightDMPController->canVal = canVal;
196 leftDMPController->flow(deltaT, leftPose, leftTwist);
197 rightDMPController->flow(deltaT, rightPose, rightTwist);
205 std::vector<double> leftTargetState = leftDMPController->getTargetPose();
206 debugOutputData.
getWriteBuffer().dmpTargets[
"leftTarget_x"] = leftTargetState[0];
207 debugOutputData.
getWriteBuffer().dmpTargets[
"leftTarget_y"] = leftTargetState[1];
208 debugOutputData.
getWriteBuffer().dmpTargets[
"leftTarget_z"] = leftTargetState[2];
209 debugOutputData.
getWriteBuffer().dmpTargets[
"leftTarget_qw"] = leftTargetState[3];
210 debugOutputData.
getWriteBuffer().dmpTargets[
"leftTarget_qx"] = leftTargetState[4];
211 debugOutputData.
getWriteBuffer().dmpTargets[
"leftTarget_qy"] = leftTargetState[5];
212 debugOutputData.
getWriteBuffer().dmpTargets[
"leftTarget_qz"] = leftTargetState[6];
213 std::vector<double> rightTargetState = rightDMPController->getTargetPose();
214 debugOutputData.
getWriteBuffer().dmpTargets[
"rightTarget_x"] = rightTargetState[0];
215 debugOutputData.
getWriteBuffer().dmpTargets[
"rightTarget_y"] = rightTargetState[1];
216 debugOutputData.
getWriteBuffer().dmpTargets[
"rightTarget_z"] = rightTargetState[2];
217 debugOutputData.
getWriteBuffer().dmpTargets[
"rightTarget_qw"] = rightTargetState[3];
218 debugOutputData.
getWriteBuffer().dmpTargets[
"rightTarget_qx"] = rightTargetState[4];
219 debugOutputData.
getWriteBuffer().dmpTargets[
"rightTarget_qy"] = rightTargetState[5];
220 debugOutputData.
getWriteBuffer().dmpTargets[
"rightTarget_qz"] = rightTargetState[6];
224 debugOutputData.
getWriteBuffer().currentPose[
"leftPose_x"] = leftPose(0, 3);
225 debugOutputData.
getWriteBuffer().currentPose[
"leftPose_y"] = leftPose(1, 3);
226 debugOutputData.
getWriteBuffer().currentPose[
"leftPose_z"] = leftPose(2, 3);
228 VirtualRobot::MathTools::eigen4f2quat(leftPose);
229 debugOutputData.
getWriteBuffer().currentPose[
"leftPose_qw"] = leftQuat.w;
230 debugOutputData.
getWriteBuffer().currentPose[
"leftPose_qx"] = leftQuat.x;
231 debugOutputData.
getWriteBuffer().currentPose[
"leftPose_qy"] = leftQuat.y;
232 debugOutputData.
getWriteBuffer().currentPose[
"leftPose_qz"] = leftQuat.z;
235 debugOutputData.
getWriteBuffer().currentPose[
"rightPose_x"] = rightPose(0, 3);
236 debugOutputData.
getWriteBuffer().currentPose[
"rightPose_y"] = rightPose(1, 3);
237 debugOutputData.
getWriteBuffer().currentPose[
"rightPose_z"] = rightPose(2, 3);
239 VirtualRobot::MathTools::eigen4f2quat(rightPose);
240 debugOutputData.
getWriteBuffer().currentPose[
"rightPose_qw"] = rightQuat.w;
241 debugOutputData.
getWriteBuffer().currentPose[
"rightPose_qx"] = rightQuat.x;
242 debugOutputData.
getWriteBuffer().currentPose[
"rightPose_qy"] = rightQuat.y;
243 debugOutputData.
getWriteBuffer().currentPose[
"rightPose_qz"] = rightQuat.z;
263 Eigen::MatrixXf leftJacobi =
264 leftIK->getJacobianMatrix(leftTCP, VirtualRobot::IKSolver::CartesianSelection::All);
265 Eigen::MatrixXf rightJacobi =
266 leftIK->getJacobianMatrix(leftTCP, VirtualRobot::IKSolver::CartesianSelection::All);
268 Eigen::VectorXf qvel;
269 qvel.resize(leftVelocitySensors.size());
270 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
272 qvel(i) = leftVelocitySensors[i]->velocity;
275 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
277 qvel(i) = rightVelocitySensors[i]->velocity;
281 leftFilteredValue = (1 - cfg->filterCoeff) * (leftForceTorque->
force - leftForceOffset) +
282 cfg->filterCoeff * leftFilteredValue;
283 rightFilteredValue = (1 - cfg->filterCoeff) * (rightForceTorque->
force - rightForceOffset) +
284 cfg->filterCoeff * rightFilteredValue;
287 rtGetRobot()->getRobotNode(
"ArmL8_Wri2")->getPoseInRootFrame();
289 rtGetRobot()->getRobotNode(
"ArmR8_Wri2")->getPoseInRootFrame();
291 Eigen::Vector3f leftForceInRootFrame = leftPose.block<3, 3>(0, 0).
transpose() *
292 leftSensorFrame.block<3, 3>(0, 0) *
294 Eigen::Vector3f rightForceInRootFrame = rightPose.block<3, 3>(0, 0).
transpose() *
295 rightSensorFrame.block<3, 3>(0, 0) *
298 controllerSensorData.
getWriteBuffer().leftPoseInRootFrame = leftPose;
299 controllerSensorData.
getWriteBuffer().rightPoseInRootFrame = rightPose;
300 controllerSensorData.
getWriteBuffer().leftTwistInRootFrame = leftTwist;
301 controllerSensorData.
getWriteBuffer().rightTwistInRootFrame = rightTwist;
302 controllerSensorData.
getWriteBuffer().leftForceInRootFrame = leftForceInRootFrame;
303 controllerSensorData.
getWriteBuffer().rightForceInRootFrame = rightForceInRootFrame;
304 controllerSensorData.
getWriteBuffer().deltaT = timeSinceLastIteration.toSecondsDouble();
308 interfaceData.
getWriteBuffer().rightTcpPoseInRootFrame = rightPose;
318 targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).inverse();
319 Eigen::Vector3f errorRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
322 rtTargetVel.block<3, 1>(0, 0) =
323 Kp_LinearVel * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) +
324 Kd_LinearVel * (-leftTwist.block<3, 1>(0, 0));
325 rtTargetVel.block<3, 1>(3, 0) =
326 Kp_AngularVel * errorRPY + Kd_AngularVel * (-leftTwist.block<3, 1>(3, 0));
328 float normLinearVelocity = rtTargetVel.block<3, 1>(0, 0).
norm();
329 if (normLinearVelocity > cfg->maxLinearVel)
331 rtTargetVel.block<3, 1>(0, 0) =
332 cfg->maxLinearVel * rtTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
335 float normAngularVelocity = rtTargetVel.block<3, 1>(3, 0).
norm();
336 if (normAngularVelocity > cfg->maxAngularVel)
338 rtTargetVel.block<3, 1>(3, 0) =
339 cfg->maxAngularVel * rtTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
342 for (
size_t i = 0; i < 6; i++)
344 leftVel(i) = rtTargetVel(i);
352 currentPose = rightPose;
357 targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).inverse();
358 Eigen::Vector3f errorRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
361 rtTargetVel.block<3, 1>(0, 0) =
362 Kp_LinearVel * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) +
363 Kd_LinearVel * (-rightTwist.block<3, 1>(0, 0));
364 rtTargetVel.block<3, 1>(3, 0) =
365 Kp_AngularVel * errorRPY + Kd_AngularVel * (-rightTwist.block<3, 1>(3, 0));
367 float normLinearVelocity = rtTargetVel.block<3, 1>(0, 0).
norm();
368 if (normLinearVelocity > cfg->maxLinearVel)
370 rtTargetVel.block<3, 1>(0, 0) =
371 cfg->maxLinearVel * rtTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
374 float normAngularVelocity = rtTargetVel.block<3, 1>(3, 0).
norm();
375 if (normAngularVelocity > cfg->maxAngularVel)
377 rtTargetVel.block<3, 1>(3, 0) =
378 cfg->maxAngularVel * rtTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
381 for (
size_t i = 0; i < 6; i++)
383 rightVel(i) = rtTargetVel(i);
388 Eigen::VectorXf leftJTV =
389 leftTCPController->calculate(leftVel,
390 cfg->KpJointLimitAvoidanceScale,
391 VirtualRobot::IKSolver::CartesianSelection::All);
392 for (
size_t i = 0; i < leftTargets.size(); ++i)
394 leftTargets.at(i)->velocity = leftJTV(i);
395 if (!leftTargets.at(i)->isValid())
399 <<
"Velocity controller target is invalid - setting to zero! set value: "
400 << leftTargets.at(i)->velocity;
401 leftTargets.at(i)->velocity = 0.0f;
405 Eigen::VectorXf rightJTV =
406 rightTCPController->calculate(rightVel,
407 cfg->KpJointLimitAvoidanceScale,
408 VirtualRobot::IKSolver::CartesianSelection::All);
409 for (
size_t i = 0; i < rightTargets.size(); ++i)
411 rightTargets.at(i)->velocity = rightJTV(i);
412 if (!rightTargets.at(i)->isValid())
416 <<
"Velocity controller target is invalid - setting to zero! set value: "
417 << rightTargets.at(i)->velocity;
418 rightTargets.at(i)->velocity = 0.0f;
426 const Ice::StringSeq& fileNames,
430 if (whichDMP ==
"Left")
432 leftDMPController->learnDMPFromFiles(fileNames);
436 if (whichDMP ==
"Right")
438 rightDMPController->learnDMPFromFiles(fileNames);
447 const Ice::DoubleSeq& rightGoals,
470 forceSign = leftGoals.at(2) - leftPose(2, 3) > 0 ? -1 : 1;
475 leftDMPController->prepareExecution(leftDMPController->eigen4f2vec(leftPose), leftGoals);
476 rightDMPController->prepareExecution(rightDMPController->eigen4f2vec(rightPose),
479 canVal = cfg->timeDuration;
483 controllerTask->start();
489 const Ice::DoubleSeq& viaPoint,
492 if (whichDMP ==
"Left")
494 leftDMPController->setViaPose(u, viaPoint);
496 if (whichDMP ==
"Right")
498 rightDMPController->setViaPose(u, viaPoint);
507 std::string debugName = cfg->debugName;
508 std::string datafieldName = debugName;
512 for (
auto& pair : dmpTargets)
514 datafieldName = pair.first +
"_" + debugName;
515 datafields[datafieldName] =
new Variant(pair.second);
519 for (
auto& pair : currentPose)
521 datafieldName = pair.first +
"_" + debugName;
522 datafields[datafieldName] =
new Variant(pair.second);
525 datafieldName =
"canVal_" + debugName;
528 datafieldName =
"forceOnHands_" + debugName;
529 datafields[datafieldName] =
531 datafieldName =
"DMPController_" + debugName;
533 debugObs->setDebugChannel(datafieldName, datafields);
548 controllerTask->stop();