22 #include <boost/algorithm/clamp.hpp>
24 #include <SimoxUtility/math/convert/mat4f_to_pos.h>
25 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
26 #include <SimoxUtility/math/compare/is_equal.h>
28 #include <VirtualRobot/MathTools.h>
32 #include <boost/archive/text_iarchive.hpp>
33 #include <boost/archive/text_oarchive.hpp>
43 const RobotUnitPtr& robotUnit,
44 const NJointControllerConfigPtr& config,
47 ARMARX_INFO <<
"creating task-space admittance controller";
48 KeypointMPControllerConfigPtr cfg = KeypointMPControllerConfigPtr::dynamicCast(config);
54 kinematicChainName = cfg->nodeSetName;
56 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
60 for (
size_t i = 0; i < rns->getSize(); ++i)
62 std::string jointName = rns->getNode(i)->getName();
63 jointNames.push_back(jointName);
68 auto casted_ct = ct->
asA<ControlTarget1DoFActuatorTorque>();
70 targets.push_back(casted_ct);
72 const SensorValue1DoFActuatorTorque* torqueSensor = sv->
asA<SensorValue1DoFActuatorTorque>();
73 const SensorValue1DoFActuatorVelocity* velocitySensor = sv->
asA<SensorValue1DoFActuatorVelocity>();
74 const SensorValue1DoFActuatorPosition* positionSensor = sv->
asA<SensorValue1DoFActuatorPosition>();
81 ARMARX_WARNING <<
"No velocity sensor available for " << jointName;
85 ARMARX_WARNING <<
"No position sensor available for " << jointName;
88 torqueSensors.push_back(torqueSensor);
89 velocitySensors.push_back(velocitySensor);
90 positionSensors.push_back(positionSensor);
94 ftsensor.initialize(rns, robotUnit, cfg->controlParamJsonFile);
99 mplib::factories::VMPFactory mpfactory;
100 mpfactory.addConfig(
"kernelSize", 100);
101 mplib::representation::VMPType vmp_type = mplib::representation::VMPType::PrincipalComponent;
102 std::shared_ptr<mplib::representation::AbstractMovementPrimitive> vmp = mpfactory.createMP(vmp_type);
103 pointVMP = std::dynamic_pointer_cast<mplib::representation::vmp::PrincipalComponentVMP>(vmp);
106 common::FTSensor::FTBufferData ftData;
107 ftData.forceBaseline.setZero();
108 ftData.torqueBaseline.setZero();
109 ftData.enableTCPGravityCompensation = cfg->enableTCPGravityCompensation;
110 ftData.tcpMass = cfg->tcpMass;
111 ftData.tcpCoMInFTSensorFrame = cfg->tcpCoMInForceSensorFrame;
114 law::TaskspaceKeypointsAdmittanceController::Config configData;
115 configData.kpImpedance = cfg->kpImpedance;
116 configData.kdImpedance = cfg->kdImpedance;
117 configData.kpAdmittance = cfg->kpAdmittance;
118 configData.kdAdmittance = cfg->kdAdmittance;
119 configData.kmAdmittance = cfg->kmAdmittance;
121 configData.kpNullspace = cfg->kpNullspace;
122 configData.kdNullspace = cfg->kdNullspace;
124 configData.currentForceTorque.setZero();
126 configData.desiredTCPTwist.setZero();
127 configData.desiredNullspaceJointAngles = cfg->desiredNullspaceJointAngles;
129 configData.torqueLimit = cfg->torqueLimit;
130 configData.qvelFilter = cfg->qvelFilter;
135 configData.numPoints = cfg->numKeypoints;
137 configData.keypointKp = cfg->keypointKp;
138 configData.keypointKi = cfg->keypointKi;
139 configData.keypointKd = cfg->keypointKd;
140 configData.maxControlValue = cfg->maxControlValue;
141 configData.maxDerivation = cfg->maxDerivation;
143 configData.pointCtrlMask = cfg->pointCtrlMask;
144 configData.currentKeypointPosition = cfg->initialKeypointPosition;
145 configData.filteredKeypointPosition = cfg->initialKeypointPosition;
146 configData.desiredKeypointPosition = cfg->initialKeypointPosition;
147 configData.isRigid = cfg->isRigid;
148 configData.fixedTranslation.setZero(cfg->numKeypoints * 3);
151 numPoints = cfg->numKeypoints;
152 initialStateEigen = cfg->initialKeypointPosition;
154 controller.s.filteredKeypointPosition = cfg->initialKeypointPosition;
156 controller.s.fixedTranslation.setZero(cfg->numKeypoints * 3);
157 controller.s.currentKeypointPosition = cfg->initialKeypointPosition;
159 controller.initPID(cfg->keypointKp, cfg->keypointKi, cfg->keypointKd, cfg->maxControlValue, cfg->maxDerivation);
166 for (
int i = 0; i < cfg->numKeypoints * 3; i++)
169 state.push_back(cfg->initialKeypointPosition[i]);
170 state.push_back(0.0);
171 rt2mp.currentState.push_back(state);
179 return "KeypointMPController";
184 return kinematicChainName;
193 timeSinceLastIteration,
200 for (
size_t i = 0; i < (unsigned)
controller.s.numPoints * 3; i++)
203 state.push_back(
controller.s.currentKeypointPosition[i]);
204 state.push_back(0.0);
218 if (rtFirstRun.load())
220 rtFirstRun.store(
false);
221 rtReady.store(
false);
229 ftsensor.compensateTCPGravity(ftSensorBuffer.
getReadBuffer());
246 const auto& desiredJointTorques =
controller.run(rtReady.load());
250 for (
size_t i = 0; i < targets.size(); ++i)
252 targets.at(i)->torque = desiredJointTorques(i);
253 if (!targets.at(i)->isValid())
255 targets.at(i)->torque = 0;
280 mpEnabled.store(enableMP);
286 return mpEnabled.load();
289 void KeypointMPController::runMP()
291 if (!rtReady.load() && !mpEnabled.load())
301 if (canVal > 1e-8 && mpRunning.load())
303 double phaseStop = 0;
306 canVal -= tau * deltaT * 1 / ((1 + phaseStop) * timeDuration);
307 currentState = pointVMP->calculateDesiredState(canVal, currentState);
309 Eigen::VectorXf desiredPosition;
310 desiredPosition.setZero(currentState.size());
311 for (
size_t i = 0; i < currentState.size(); i++)
313 desiredPosition[i] = currentState[i][0];
334 vec.head(3) = pose.block<3, 1>(0, 3);
335 vec.tail(3) = VirtualRobot::MathTools::eigen4f2rpy(pose);
341 datafields[name +
"_x"] =
new Variant(vec(0));
342 datafields[name +
"_y"] =
new Variant(vec(1));
343 datafields[name +
"_z"] =
new Variant(vec(2));
344 datafields[name +
"_rx"] =
new Variant(vec(3));
345 datafields[name +
"_ry"] =
new Variant(vec(4));
346 datafields[name +
"_rz"] =
new Variant(vec(5));
351 for (
int i = 0; i < vec.size(); i++)
363 datafields[pair.first] =
new Variant(pair.second);
463 debugObs->setDebugChannel(
"KeypointMPController", datafields);
483 if (name ==
"kpImpedance")
488 else if (name ==
"kdImpedance")
493 else if (name ==
"kpAdmittance")
498 else if (name ==
"kdAdmittance")
503 else if (name ==
"kmAdmittance")
508 else if (name ==
"kpNullspace")
513 else if (name ==
"kdNullspace")
520 ARMARX_ERROR << name <<
" is not supported by TaskSpaceAdmittanceController";
534 ftSensorBuffer.
getWriteBuffer().enableTCPGravityCompensation =
true;
541 ftSensorBuffer.
getWriteBuffer().enableTCPGravityCompensation =
true;
542 ftSensorBuffer.
getWriteBuffer().tcpCoMInFTSensorFrame = tcpCoMInFTSensorFrame;
548 rtReady.store(
false);
558 pointVMP->prepareExecution(goal, initialState, 1.0);
559 mplib::representation::MPStateVec initState = mplib::core::SystemState::convert2DArrayToStates<mplib::representation::MPState>(initialState);
564 timeDuration = duration;
565 pointVMP->prepareExecution(goal, initialState, 1.0);
566 mplib::representation::MPStateVec initState = mplib::core::SystemState::convert2DArrayToStates<mplib::representation::MPState>(initialState);
567 mpRunning.store(
true);
572 pointVMP->prepareExecution(goal, initialState, 1.0);
573 mplib::representation::MPStateVec initState = mplib::core::SystemState::convert2DArrayToStates<mplib::representation::MPState>(initialState);
583 mpRunning.store(
false);
588 mpRunning.store(
false);
593 mpRunning.store(
true);
598 if (mpRunning.load())
607 return !mpRunning.load();
612 std::vector<mplib::core::SampledTrajectory> trajs;
613 for (
auto& file : fileList)
615 mplib::core::SampledTrajectory traj;
616 traj.readFromCSVFile(file);
617 trajs.push_back(traj);
619 pointVMP->learnFromTrajectories(trajs);
622 initialState.clear();
625 for (
size_t i = 0; i < trajs[0].dim(); i++)
630 state.push_back(initialStateEigen[i]);
631 state.push_back(0.0);
632 initialState.push_back(state);
633 goal.push_back(trajs[0].rbegin()->getPosition(i));
663 return "notImplemented";
676 std::vector<double> dummy;
677 dummy.push_back(0.0);
688 ftSensorBuffer.
getWriteBuffer().enableTCPGravityCompensation = toggle;
690 rtReady.store(
false);
695 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(kinematicChainName);
697 ARMARX_IMPORTANT <<
"rt preactivate controller with target pose\n\n" << currentPose;
700 controller.s.previousTargetPose = currentPose;
705 Eigen::VectorXf fixedTranslation;
706 fixedTranslation.setZero(
controller.s.currentKeypointPosition.size());
710 for (
int i = 0; i < numPoints; i++)
712 fixedTranslation.segment(3*i, 3) =
controller.s.currentKeypointPosition.segment(3*i, 3) - currentPose.block<3, 1>(0, 3);
716 controller.s.fixedTranslation = fixedTranslation;
725 runTask(
"KeypointMPController", [&]
730 while (
getState() == eManagedIceObjectStarted)
736 c.waitForCycleDuration();
749 void KeypointMPController::resetKeypoints(
const int n_points,
const float keypoint_stiffness,
const bool is_rigid,
const Eigen::VectorXf &ctrl_mask,
const Eigen::VectorXf& init_keypoints_position,
const Ice::Current &)
751 numPoints = n_points;