66 const NJointControllerConfigPtr& config,
97 controlTargets_.platformTarget =
99 ControlModes::HolonomicPlatformVelocity)
102 <<
"The actuator " << robotUnit->getRobotPlatformName() <<
" has no control mode "
103 << ControlModes::HolonomicPlatformVelocity;
108 jointName, ControlModes::Velocity1DoF);
111 controlTargets_.jointTargets.push_back(controlTarget);
118 jointName, ControlModes::Position1DoF);
121 controlTargets_.handTargets.push_back(controlTarget);
143 svGlobalRobotLocalization_ =
152 std::vector<bool> isJointLimitless;
155 const auto node = robot_->getRobotNode(jointName);
156 isJointLimitless.push_back(node->isLimitless());
168 pidArm_->preallocate(nDofArm);
174 pidPlatform_.preallocate(2);
187 const std::string tcpNodeName =
"Hand R TCP";
191 debugRobot_ = robot->clone();
195 publishTcpNode_ = debugRobot_->getRobotNode(tcpNodeName);
198 rtTcpNode_ = robot_->getRobotNode(tcpNodeName);
214 .platformPosDiff = 0,
215 .platformOriDiff = 0,
217 .targetState = trajectory_->initialPoint(),
218 .currentTcpPose = Eigen::Isometry3f{rtTcpNode_->getGlobalPose()},
219 .currentPlatformPose = Eigen::Isometry3f{robot_->getGlobalPose()},
220 .isControllerActive =
false};
222 bufferRtToOnPublish_.reinitAllBuffers(initDebugData);
237 const IceUtil::Time& timeSinceLastIteration)
241 auto& debugData = bufferRtToOnPublish_.getWriteBuffer();
268 const auto trajPointOpt = trajectory_->at(
timestamp);
272 if (not trajPointOpt.has_value())
277 controlTargets_.platformTarget->velocityX = 0;
278 controlTargets_.platformTarget->velocityY = 0;
279 controlTargets_.platformTarget->velocityRotation = 0;
282 for (
auto*
const jointControlTarget : controlTargets_.jointTargets)
284 jointControlTarget->velocity = 0;
293 debugData.localTimestamp = trajPoint.timestampMicroSeconds;
294 debugData.targetState = trajPoint;
295 debugData.currentTcpPose = Eigen::Isometry3f{rtTcpNode_->getGlobalPose()};
296 debugData.currentPlatformPose = Eigen::Isometry3f{robot_->getGlobalPose()};
304 const Eigen::Vector2f global_P_robot_target{trajPoint.jointValuesPlatform.at(0),
305 trajPoint.jointValuesPlatform.at(1)};
306 const double targetOrientationGlobal = trajPoint.jointValuesPlatform.at(2);
309 const auto global_T_robot = svGlobalRobotLocalization_->global_T_root;
310 const Eigen::Vector3f rpy = simox::math::mat4f_to_rpy(global_T_robot);
311 const float globalOrientation = rpy.z();
312 const Eigen::Vector2f global_P_robot = global_T_robot.block<2, 1>(0, 3);
314 const float measuredOrientation = globalOrientation;
317 timeSinceLastIteration.toSecondsDouble(), global_P_robot, global_P_robot_target);
318 opidPlatform_.update(timeSinceLastIteration.toSecondsDouble(),
319 static_cast<double>(measuredOrientation),
320 targetOrientationGlobal);
323 debugData.platformPosDiff = (global_P_robot_target - global_P_robot).
norm();
324 debugData.platformOriDiff =
325 static_cast<float>(targetOrientationGlobal) - measuredOrientation;
335 const Eigen::Rotation2Df local_R_global(-measuredOrientation);
336 const Eigen::Vector2f& vPosError = local_R_global * pidPlatform_.getControlValue();
337 const Eigen::Vector2f vVelFFRobotFrame =
338 local_R_global * Eigen::Vector2f(trajPoint.jointVelocitiesPlatform.at(0),
339 trajPoint.jointVelocitiesPlatform.at(1));
341 const auto& vFF = trajPoint.jointVelocitiesPlatform;
353 constexpr float ffFactorPlatform = 1.0;
358 controlTargets_.platformTarget->velocityX =
359 ffFactorPlatform * vVelFFRobotFrame.x() + vPosError.x();
360 controlTargets_.platformTarget->velocityY =
361 ffFactorPlatform * vVelFFRobotFrame.y() + vPosError.y();
367 controlTargets_.platformTarget->velocityRotation =
368 ffFactorPlatform * vFF.at(2) +
369 static_cast<float>(opidPlatform_.getControlValue());
376 ARMARX_CHECK_EQUAL(controlTargets_.jointTargets.size(), trajPoint.jointValues.size());
378 trajPoint.jointVelocities.size());
383 const auto toEigen = [](
const std::vector<double>& vec) -> Eigen::VectorXf
385 Eigen::VectorXf eigenVec(vec.size());
386 for (std::size_t i = 0; i < vec.size(); i++)
388 eigenVec(i) =
static_cast<float>(vec.at(i));
396 const Eigen::VectorXf jointPositionTargets =
toEigen(trajPoint.jointValues);
399 Eigen::VectorXf jointPositionMeasured(jointSensorValues_.size());
400 for (std::size_t i = 0; i < jointSensorValues_.size(); i++)
402 jointPositionMeasured(i) = jointSensorValues_.at(i)->position;
407 for (std::size_t i = 0; i < jointSensorValues_.size(); i++)
409 debugData.jointPosDiff.at(i) =
410 std::abs(jointPositionTargets(i) - jointPositionMeasured(i));
414 pidArm_->update(timeSinceLastIteration.toSecondsDouble(),
415 jointPositionMeasured,
416 jointPositionTargets);
419 const Eigen::VectorXf& jointVelocityForPosError = pidArm_->getControlValue();
421 for (std::size_t i = 0; i < controlTargets_.jointTargets.size(); i++)
423 auto*
const jointControlTarget = controlTargets_.jointTargets.at(i);
427 const double jointVelTarget = trajPoint.jointVelocities.at(i);
431 jointControlTarget->velocity =
432 static_cast<float>(jointVelTarget) + jointVelocityForPosError(i);
434 if (not jointControlTarget->isValid())
437 <<
". Value: " << jointControlTarget->velocity;
446 trajPoint.handJointValues.size());
447 for (std::size_t i = 0; i < controlTargets_.handTargets.size(); i++)
449 auto*
const handControlTarget = controlTargets_.handTargets.at(i);
450 const double jointPosTarget = trajPoint.handJointValues.at(i);
451 handControlTarget->position =
static_cast<float>(jointPosTarget);
455 bufferRtToOnPublish_.commitWrite();
481 const auto& debugData = bufferRtToOnPublish_.getUpToDateReadBuffer();
483 datafields[
"localTimestamp"] =
new Variant(debugData.localTimestamp);
485 datafields[
"platform/dpos"] =
new Variant(debugData.platformPosDiff);
486 datafields[
"platform/dori"] =
new Variant(debugData.platformOriDiff);
489 for (
const auto& [jointName, diff] :
490 ranges::views::zip(jointNames_, debugData.jointPosDiff))
492 datafields[jointName +
"/dpos"] =
new Variant(diff);
495 const float tcpDiff = [&]() ->
float
497 namespace rv = ranges::views;
500 std::map<std::string, float> targetJointValues;
501 for (
const auto& [jointName, jointValue] :
502 rv::zip(jointNames_, debugData.targetState.jointValues))
504 targetJointValues.emplace(jointName, jointValue);
507 const Eigen::Isometry3f targetGlobalPose =
508 Eigen::Translation3f{
509 static_cast<float>(debugData.targetState.jointValuesPlatform.at(0)),
510 static_cast<float>(debugData.targetState.jointValuesPlatform.at(1)),
513 static_cast<float>(debugData.targetState.jointValuesPlatform.at(2)),
514 Eigen::Vector3f::UnitZ()};
516 debugRobot_->setJointValues(targetJointValues);
517 debugRobot_->setGlobalPose(targetGlobalPose.matrix());
519 const Eigen::Isometry3f targetTcpPose(publishTcpNode_->getGlobalPose());
521 const Eigen::Isometry3f tcpDiffTf = debugData.currentTcpPose.inverse() * targetTcpPose;
523 auto batchPrx = debugDrawer->ice_batchOneway();
528 batchPrx->setSphereDebugLayerVisu(
531 ::armarx::DrawColor{1, 0, 0, 0},
534 batchPrx->setSphereDebugLayerVisu(
536 new armarx::Vector3(Eigen::Vector3f{debugData.currentTcpPose.translation()}),
537 ::armarx::DrawColor{0, 1, 0, 0},
540 batchPrx->setPoseDebugLayerVisu(
"tcp_target_pose",
toIce(targetTcpPose.matrix()));
541 batchPrx->setPoseDebugLayerVisu(
"tcp_current_pose",
542 toIce(debugData.currentTcpPose.matrix()));
547 batchPrx->setSphereDebugLayerVisu(
550 ::armarx::DrawColor{1, 0, 0, 0},
553 batchPrx->setSphereDebugLayerVisu(
"platform_current",
555 debugData.currentPlatformPose.translation()}),
556 ::armarx::DrawColor{0, 1, 0, 0},
559 batchPrx->setPoseDebugLayerVisu(
"platform_target_pose",
560 toIce(targetGlobalPose.matrix()));
562 batchPrx->setPoseDebugLayerVisu(
"platform_current_pose",
563 toIce(debugData.currentPlatformPose.matrix()));
566 batchPrx->ice_flushBatchRequests();
570 return tcpDiffTf.translation().norm();
573 datafields[
"tcpDiff"] =
new Variant(tcpDiff);
580 if (whateverFlag_.load())
582 whatever_.push_back(debugData);