ReachOutToHumanPose.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package RobotSkillTemplates::HandOverGroup
17  * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "ReachOutToHumanPose.h"
24 #include <VirtualRobot/MathTools.h>
25 #include <VirtualRobot/RobotNodeSet.h>
26 
28 
30 
31 //#include <ArmarXCore/core/time/TimeUtil.h>
35 
39 #include <RobotAPI/interface/units/RobotUnit/NJointCartesianVelocityControllerWithRamp.h>
46 
47 
48 using namespace armarx;
49 using namespace visionx;
50 using namespace HandOverGroup;
51 
52 // DO NOT EDIT NEXT LINE
53 ReachOutToHumanPose::SubClassRegistry
54  ReachOutToHumanPose::Registry(ReachOutToHumanPose::GetName(),
55  &ReachOutToHumanPose::CreateInstance);
56 
57 #define ENABLE_DEBUG_DRAWER 0
58 
59 void
60 ReachOutToHumanPose::onEnter()
61 {
62  // put your user code for the enter-point here
63  // execution time should be short (<100ms)
64  // ManagedIceObjectPtr obj = ManagedIceObjectPtr::dynamicCast(getContext());
65  // obj->getIceManager()->subscribeTopic()
66 }
67 
68 void
69 ReachOutToHumanPose::run()
70 {
71  viz::ScopedClient arviz = viz::Client::createFromTopic("ReachOutToHumanPose", getArvizTopic());
72  arviz.commit({arviz.layer("HandOverState")}); // Clear layer.
73 
75  getContext<HandOverGroupStatechartContextExtension>();
76  c->getOpenPoseEstimation()->start3DPoseEstimation();
77 
79  CycleUtil cycle(10);
80  filters::PoseMedianFilter lwristFilter(in.getPoseMedianFilterSize()),
81  rwristFilter(in.getPoseMedianFilterSize());
82  filters::PoseAverageFilter headIKTargetFilter(50);
83  std::vector<filters::AverageFilter> targetPositionFilter(3), targetVelocityFilter(3);
84  for (auto& filter : targetPositionFilter)
85  {
86  filter.windowFilterSize = in.getTargetPositionAverageFilterSize();
87  }
88  for (auto& filter : targetVelocityFilter)
89  {
90  filter.windowFilterSize = in.getTargetPositionAverageFilterSize();
91  }
92  float maxTCPVelocity = in.getMaxTCPVelocity();
93  float considerForceDistanceThreshold = in.getConsiderForceDistanceThreshold();
94  auto robot = getLocalRobot();
95 
96  {
97  auto node = robot->getRobotNode("ArmR3_Sho2");
98  node->setJointLimits(node->getJointLimitLow(), VirtualRobot::MathTools::deg2rad(90));
99  }
100  {
101  auto node = robot->getRobotNode("ArmR5_Elb1");
102  node->setJointLimits(VirtualRobot::MathTools::deg2rad(5), node->getJointLimitHigh());
103  }
104  {
105  auto node = robot->getRobotNode("ArmR1_Cla1");
106  node->setJointLimits(VirtualRobot::MathTools::deg2rad(-45),
107  VirtualRobot::MathTools::deg2rad(45));
108  }
109 
110  {
111  auto node = robot->getRobotNode("ArmL3_Sho2");
112  node->setJointLimits(node->getJointLimitLow(), VirtualRobot::MathTools::deg2rad(90));
113  }
114  {
115  auto node = robot->getRobotNode("ArmL5_Elb1");
116  node->setJointLimits(VirtualRobot::MathTools::deg2rad(5), node->getJointLimitHigh());
117  }
118  {
119  auto node = robot->getRobotNode("ArmL1_Cla1");
120  node->setJointLimits(VirtualRobot::MathTools::deg2rad(-45),
121  VirtualRobot::MathTools::deg2rad(45));
122  }
123 
124  auto cameraRobot = getLocalRobot(); // receives new copy
125  ARMARX_CHECK_EXPRESSION(robot.get() != cameraRobot.get());
126  filters::AverageFilter forceMagnitudeAvgFilter;
127  forceMagnitudeAvgFilter.windowFilterSize = 10;
128 
129  getHeadIKUnit()->request();
130 
131  // look straight ahead
132  ARMARX_INFO << "InitialHeadIKTarget(): " << in.getInitialHeadIKTarget()->output();
133  getHeadIKUnit()->setHeadTarget(in.getHeadIKNodeSet(), in.getInitialHeadIKTarget());
134  TimeUtil::MSSleep(1000);
135 
136  auto kinematicChainName = in.getKinematicChainName();
137  MultiDimPIDController pid(in.getKp(), 0, 0);
138  IceUtil::Time lastTimestamp = armarx::TimeUtil::GetTime();
140  auto nodeset = robot->getRobotNodeSet(kinematicChainName);
141  auto tcp = nodeset->getTCP();
142  auto kinematicRootName = nodeset->getKinematicRoot()->getName();
143 
144  ARMARX_INFO << VAROUT(kinematicRootName)
145  << " position in root: " << nodeset->getKinematicRoot()->getPositionInRootFrame();
146  FramedDirectionPtr targetVelocity;
147  DatafieldRefPtr forceTorqueRef = DatafieldRefPtr::dynamicCast(
148  getForceTorqueObserver()->getDataFieldRef(new DataFieldIdentifier(
149  getForceTorqueObserver()->getObserverName(), in.getFTSensorName(), "forces")));
150  ARMARX_CHECK_EXPRESSION(forceTorqueRef);
151  DatafieldRefPtr nulledForceTorqueRef;
152  NJointCartesianVelocityControllerWithRampConfigPtr ctrlCfg =
153  new NJointCartesianVelocityControllerWithRampConfig();
154  ctrlCfg->KpJointLimitAvoidance = 0;
155  ctrlCfg->jointLimitAvoidanceScale = 1;
156  ctrlCfg->mode = CartesianSelectionMode::eAll;
157  ctrlCfg->nodeSetName = kinematicChainName;
158  ctrlCfg->tcpName = tcp->getName();
159  ctrlCfg->maxNullspaceAcceleration = 2;
160  ctrlCfg->maxPositionAcceleration = in.getTCPAcceleration();
161  ctrlCfg->maxOrientationAcceleration = 1;
162 
163  CartesianPositionController posController(tcp);
164  posController.maxOriVel = in.getMaxOrientationVelocity();
165  posController.maxPosVel = in.getMaxTCPVelocity();
166  posController.KpOri = in.getKpOrientation();
167  posController.KpPos = in.getKp();
168 
169  auto ctrlName = "ReachOutToHumanTCPCtrl";
170  TIMING_START(NJointCtrlCreation);
171  ARMARX_INFO << deactivateSpam(1) << "Getting old controller";
172  if (auto oldCtrl = getRobotUnit()->getNJointController(ctrlName))
173  {
174  ARMARX_INFO << deactivateSpam(1) << "got old controller";
175  while (oldCtrl->isControllerActive())
176  {
177  oldCtrl->deactivateController();
178  ARMARX_INFO << deactivateSpam(1) << "Waiting for old controller to be deactivated";
179  usleep(30000);
180  }
181  ARMARX_INFO << deactivateSpam(1) << "deleting old controller";
183  usleep(100000);
184  }
185  ARMARX_INFO << deactivateSpam(1) << "Getting new controller";
186  auto baseCtrl = getRobotUnit()->createNJointController(
187  "NJointCartesianVelocityControllerWithRamp", ctrlName, ctrlCfg);
188  ARMARX_CHECK_EXPRESSION(baseCtrl);
189  NJointCartesianVelocityControllerWithRampInterfacePrx ctrl =
190  NJointCartesianVelocityControllerWithRampInterfacePrx::checkedCast(baseCtrl);
191  TIMING_END(NJointCtrlCreation);
192  ARMARX_CHECK_EXPRESSION(ctrl) << baseCtrl->ice_ids();
193  ctrl->activateController();
194 
195  auto targetOrientation = in.getHandOrientation();
196  IceUtil::Time startTime = TimeUtil::GetTime();
197 
198  RemoteRobot::synchronizeLocalClone(robot, getRobotStateComponent());
199 
200  const Eigen::Vector3f offset{0, 0, 300};
201  Eigen::Vector3f idlePosi = tcp->getPositionInRootFrame() + offset;
202  FramedPositionPtr idlePosition =
203  new FramedPosition(idlePosi, robot->getRootNode()->getName(), robot->getName());
204  // in.getIdlePosition();
205 
206  bool drawDebugInfos = in.getDrawDebugInfos();
207  FramedPositionPtr lastIKTarget;
208  while (!isRunningTaskStopped()) // stop run function if returning true
209  {
210  viz::Layer vizLayer = arviz.layer("HandOverState");
211 
212  auto now = armarx::TimeUtil::GetTime();
213  auto timeSinceSinceStart = now - startTime;
214  IceUtil::Time duration = now - lastTimestamp;
215  lastTimestamp = now;
216 
217  c->getImageSourceSelectionTopic()->setImageSource("OpenPoseEstimationResult", 5000);
218 
219  // do your calculations
220  std::vector<Keypoint3DMap> keypointList;
222  std::tie(timestamp, keypointList) = c->getPoseData()->getLatestData();
223  RemoteRobot::synchronizeLocalClone(robot, getRobotStateComponent());
225  cameraRobot, getRobotStateComponent(), timestamp.toMicroSeconds());
226 
227  Keypoint3DMap poseData = getClosestPerson(keypointList);
228  int validKeypoints = 0;
229  for (auto& pair : poseData)
230  {
231  if (isKeypointValid(pair.second))
232  {
233  validKeypoints++;
234  }
235  }
236 
237 
238  Keypoint3D rwrist = poseData["RWrist"];
239  Vector3Ptr rwristPosition = new Vector3(rwrist.x, rwrist.y, rwrist.z);
240  bool validTarget = false;
241  if (isKeypointValid(rwrist))
242  {
243  rwristFilter.update(now.toMicroSeconds(), new Variant(rwristPosition));
244  }
245  auto tmp = rwristFilter.getValue();
246  if (tmp)
247  {
248  Vector3Ptr filteredRWristPosition = VariantPtr::dynamicCast(tmp)->get<Vector3>();
249  ARMARX_CHECK_EXPRESSION(filteredRWristPosition);
250  FramedPositionPtr globalrWristPosition =
252  filteredRWristPosition->toEigen(), in.getCameraFrameName(), robot->getName())
253  .toGlobal(robot);
254  // ARMARX_INFO << deactivateSpam(1) << VAROUT(*globalrWristPosition);
255  if (drawDebugInfos)
256  {
257 #if ENABLE_DEBUG_DRAWER
258  this->getDebugDrawerTopic()->setSphereVisu(
259  "HandOverState",
260  "rwrist",
261  globalrWristPosition,
262  DrawColor{1.0f, 0.0f, 0.0f, rwrist.confidence},
263  30);
264 #else
265  vizLayer.add(viz::Sphere("rwrist")
266  .position(globalrWristPosition->toEigen())
267  .color(simox::Color::red(255, 255 * rwrist.confidence))
268  .radius(30));
269 #endif
270  getDebugObserver()->setDebugChannel(
271  "HandOverState",
272  {
273  {"rwristpoint_z", new Variant(rwristPosition->z)},
274  {"rwristpoint_z_filtered", new Variant(filteredRWristPosition->z)},
275  });
276  }
277 
278  rwristPosition = filteredRWristPosition;
279  validTarget = true;
280  }
281  Keypoint3D lwrist = poseData["LWrist"];
282  Vector3Ptr lwristPosition = new Vector3(lwrist.x, lwrist.y, lwrist.z);
283  if (isKeypointValid(lwrist))
284  {
285  lwristFilter.update(now.toMicroSeconds(), new Variant(lwristPosition));
286  }
287  tmp = lwristFilter.getValue();
288  if (tmp)
289  {
290  lwristPosition = VariantPtr::dynamicCast(tmp)->get<Vector3>();
291  ARMARX_CHECK_EXPRESSION(lwristPosition);
292  FramedPositionPtr globallWristPosition =
293  FramedPosition(lwristPosition->toEigen(), in.getCameraFrameName(), robot->getName())
294  .toGlobal(robot);
295  // ARMARX_INFO << deactivateSpam(1) << VAROUT(*globallWristPosition) << VAROUT(robot->getGlobalPose());
296  if (drawDebugInfos)
297  {
298 #if ENABLE_DEBUG_DRAWER
299  this->getDebugDrawerTopic()->setSphereVisu(
300  "HandOverState",
301  "lwrist",
302  globallWristPosition,
303  DrawColor{0.0f, 1.0f, 0.0f, lwrist.confidence},
304  30);
305 #else
306  vizLayer.add(viz::Sphere("lwrist")
307  .position(globallWristPosition->toEigen())
308  .color(simox::Color::green(255, 255 * lwrist.confidence))
309  .radius(30));
310 #endif
311  }
312  validTarget = true;
313  }
314  // ARMARX_INFO << deactivateSpam(1) << "Filtered wrist data";
315  float leftHandDistance = lwristPosition && isKeypointValid(lwrist)
316  ? lwristPosition->toEigen().norm()
318  float rightHandDistance = rwristPosition && isKeypointValid(rwrist)
319  ? rwristPosition->toEigen().norm()
321 
322  Vector3Ptr currentHandPosition =
323  leftHandDistance < rightHandDistance ? lwristPosition : rwristPosition;
324 
325  if (drawDebugInfos)
326  {
327  getDebugObserver()->setDebugChannel(
328  "ReachOutToHuman",
329  {{"zDiffLShoulder",
330  new Variant(std::abs(poseData["LWrist"].z - poseData["LShoulder"].z))},
331  {"zDiffNeckR", new Variant(std::abs(poseData["RWrist"].z - poseData["Neck"].z))},
332  {"zDiffNeckL", new Variant(std::abs(poseData["LWrist"].z - poseData["Neck"].z))}});
333  }
334 
335 
336  Eigen::Vector3f headIkTarget = getHeadIKTarget(poseData);
337  FramedPositionPtr globalHeadIkTarget =
338  FramedPosition(headIkTarget, in.getCameraFrameName(), robot->getName())
339  .toGlobal(cameraRobot);
340  globalHeadIkTarget->z = std::max(in.getMinimumGazeZPosition(), globalHeadIkTarget->z);
341 
342  if (validKeypoints > 3 && !in.getHeadIKNodeSet().empty() && headIkTarget.norm() > 0)
343  {
344  if (drawDebugInfos)
345  {
346 #if ENABLE_DEBUG_DRAWER
347  this->getDebugDrawerTopic()->setSphereVisu("HandOverState",
348  "Median",
349  globalHeadIkTarget,
350  DrawColor{1.0f, 1.0f, 0.0f, 1.0f},
351  50);
352 #else
353  vizLayer.add(viz::Sphere("Median")
354  .position(globalHeadIkTarget->toEigen())
355  .color(simox::Color::yellow())
356  .radius(50));
357 #endif
358  }
359  headIKTargetFilter.update(now.toMicroSeconds(), new Variant(globalHeadIkTarget));
360  auto tmp = headIKTargetFilter.getValue();
362  FramedPositionPtr globalFilteredMedianKeypoint =
363  VariantPtr::dynamicCast(tmp)->get<FramedPosition>();
364  ARMARX_CHECK_EXPRESSION(globalFilteredMedianKeypoint);
365  if ((TimeUtil::GetTime() - startTime).toSecondsDouble() > 1.3)
366  {
367  if (!lastIKTarget ||
368  (lastIKTarget->toEigen() - globalFilteredMedianKeypoint->toEigen()).norm() >
369  100)
370  {
371  getHeadIKUnit()->setHeadTarget(in.getHeadIKNodeSet(),
372  globalFilteredMedianKeypoint);
373  lastIKTarget = globalFilteredMedianKeypoint;
374  // ARMARX_INFO << deactivateSpam(1) << "HeadIK Target: " << *globalFilteredMedianKeypoint;
375  }
376  }
377  }
378  else
379  {
380 #if ENABLE_DEBUG_DRAWER
381  this->getDebugDrawerTopic()->removeSphereVisu("HandOverState", "Median");
382 #else
383  // Don't add Median to the layer.
384 #endif
385  }
386 
387 
388  float currentHumanReachDistance =
389  headIkTarget.norm() == 0 && currentHandPosition->toEigen().norm() > 100
390  ? 0
391  : std::abs((currentHandPosition->toEigen() - headIkTarget)(2));
392  bool humanIsReachingOut = currentHumanReachDistance > in.getHumanMinimumReachOutDistance();
393  // ARMARX_INFO << deactivateSpam(1) << VAROUT(currentHumanReachDistance) << VAROUT(humanIsReachingOut);
394  Eigen::Vector3f currentTargetVec = currentHandPosition->toEigen();
395  for (int i = 0; i < 3; ++i)
396  {
397  targetPositionFilter.at(i).update(now.toMicroSeconds(),
398  new Variant(currentTargetVec(i)));
399  }
400  Eigen::Vector3f currentFilteredTargetPositionVec;
401  for (int i = 0; i < 3; ++i)
402  {
403  currentFilteredTargetPositionVec(i) = targetPositionFilter.at(i).getValue()->getFloat();
404  }
405  // ARMARX_INFO << deactivateSpam(1) << "Filtered target position ";
406  FramedPositionPtr targetPositioninRootFrame = new FramedPosition(
407  currentFilteredTargetPositionVec, in.getCameraFrameName(), cameraRobot->getName());
408  targetPositioninRootFrame->changeFrame(robot, robot->getRootNode()->getName());
409 
410  // FramedPositionPtr localFramedPosition;
412  // float currentReachDistance = tcp->getTransformationFrom(nodeset->getKinematicRoot()).block<3,1>(0,3).norm();
413  FramedPositionPtr targetInKinematicRootFrame =
414  new FramedPosition(*targetPositioninRootFrame);
415  targetInKinematicRootFrame->changeFrame(robot, kinematicRootName);
416  float reachDistanceToTarget = targetInKinematicRootFrame->toEigen().norm();
417  ARMARX_INFO << deactivateSpam(1) << VAROUT(reachDistanceToTarget);
418  getDebugObserver()->setDebugDatafield(
419  "ReachOutToHuman", "reachDistanceToTarget", new Variant(reachDistanceToTarget));
420  float reachDistanceToTargetClamped = reachDistanceToTarget;
421  if (reachDistanceToTarget > in.getDistanceThresholdSoft() &&
422  reachDistanceToTarget < in.getDistanceThreshold())
423  {
424  Eigen::Vector3f targetPositioninKinematicRootFrameClamped =
425  targetInKinematicRootFrame->toEigen().normalized() * in.getDistanceThresholdSoft();
426  targetPositioninRootFrame =
427  new FramedPosition(targetPositioninKinematicRootFrameClamped,
428  targetInKinematicRootFrame->frame,
429  targetInKinematicRootFrame->agent);
430  targetPositioninRootFrame->changeFrame(robot, robot->getRootNode()->getName());
431  reachDistanceToTargetClamped = targetPositioninKinematicRootFrameClamped.norm();
432  }
433  if (drawDebugInfos)
434  {
435  getDebugObserver()->setDebugChannel(
436  "ReachOutToHuman",
437  {{"targetPositioninRootFrameX", new Variant(targetPositioninRootFrame->x)},
438  {"targetPositioninRootFrameY", new Variant(targetPositioninRootFrame->y)},
439  {"targetPositioninRootFrameZ", new Variant(targetPositioninRootFrame->z)},
440  {"targetPositioninRootNorm",
441  new Variant(targetPositioninRootFrame->toEigen().norm())},
442  {"reachDistanceToTargetClamped", new Variant(reachDistanceToTargetClamped)}});
443  }
444 
445  float distanceToTarget =
446  (tcp->getPositionInRootFrame() - targetPositioninRootFrame->toEigen()).norm();
447 
448  bool returnToIdlePose =
449  reachDistanceToTarget > in.getDistanceThreshold() || !validTarget ||
450  !humanIsReachingOut || validKeypoints < 5 ||
451  timeSinceSinceStart.toMilliSeconds() < in.getMinWaitBeforeReachTime();
452  if (returnToIdlePose)
453  {
454  targetPositioninRootFrame = in.getIdlePosition();
455  }
456  else
457  {
458  idlePosition = in.getIdlePosition();
459  targetPositioninRootFrame->y -= in.getTargetYOffset();
460  targetPositioninRootFrame->z += in.getTargetZOffset();
461  }
462  // ARMARX_CHECK_EXPRESSION(lwristPosition);
463  // ARMARX_CHECK_EXPRESSION(lwristPosition);
464  ARMARX_CHECK_EXPRESSION(lwristPosition);
465 
466  FramedPositionPtr globalTargetPosition = targetPositioninRootFrame->toGlobal(robot);
467  if (drawDebugInfos)
468  {
469 #if ENABLE_DEBUG_DRAWER
470  getDebugDrawerTopic()->setSphereVisu("HandOverState",
471  "TargetPosition",
472  globalTargetPosition,
473  DrawColor{0.0f, 1.0f, 1.0f, 1.0},
474  30);
475  getDebugDrawerTopic()->setLineVisu("HandOverState",
476  "ReachOutLine",
477  globalTargetPosition,
478  globalHeadIkTarget,
479  5,
480  humanIsReachingOut ? DrawColor{0.0f, 1.0f, 0.0f, 1.0}
481  : DrawColor{1.0f, 0, 0, 1.0});
482 #else
483  vizLayer.add(viz::Sphere("TargetPosition")
484  .position(globalTargetPosition->toEigen())
485  .color(simox::Color::cyan())
486  .radius(30));
487  vizLayer.add(
488  viz::Cylinder("ReachOutLine")
489  .fromTo(globalTargetPosition->toEigen(), globalHeadIkTarget->toEigen())
490  .radius(5)
491  .color(humanIsReachingOut ? simox::Color::green() : simox::Color::red()));
492 #endif
493  }
494 
495 
496  pid.update(duration.toMicroSecondsDouble(),
497  tcp->getPositionInRootFrame(),
498  targetPositioninRootFrame->toEigen());
499  Eigen::Vector3f targetVelocityVec = pid.getControlValue();
500  if (targetVelocityVec.norm() > maxTCPVelocity)
501  {
502  targetVelocityVec = targetVelocityVec.normalized() * maxTCPVelocity;
503  }
504  if (distanceToTarget < considerForceDistanceThreshold)
505  {
506  targetVelocityVec = Eigen::Vector3f::Zero();
507  if (!nulledForceTorqueRef)
508  {
509  nulledForceTorqueRef = DatafieldRefPtr::dynamicCast(
510  getForceTorqueObserver()->createNulledDatafield(forceTorqueRef));
511  }
512  FramedDirectionPtr nulledFT =
513  nulledForceTorqueRef->getDataField()->get<FramedDirection>();
514  float forceMagnitude = nulledFT->toEigen().norm();
515  if (drawDebugInfos)
516  {
517  getDebugObserver()->setDebugChannel(
518  "ReachOutToHuman",
519  {{"ForceX", new Variant(nulledFT->x)},
520  {"ForceZ", new Variant(nulledFT->z)},
521  {"ForceMagnitude", new Variant(forceMagnitude)}});
522  }
523  forceMagnitudeAvgFilter.update(now.toMicroSeconds(), new Variant(forceMagnitude));
524  float forceMagnitudeFiltered = forceMagnitudeAvgFilter.getValue()->getFloat();
525  if (drawDebugInfos)
526  {
527  getDebugObserver()->setDebugDatafield("ReachOutToHuman",
528  "forceMagnitudeFiltered",
529  new Variant(forceMagnitudeFiltered));
530  }
531 
532  ARMARX_INFO << deactivateSpam(1) << VAROUT(forceMagnitude)
533  << " threshold: " << in.getForceThreshold();
534  if (forceMagnitude > in.getForceThreshold())
535  {
536  ARMARX_IMPORTANT << "ForceThresholdReached: " << forceMagnitude;
537  this->emitForceThresholdReached();
538  break;
539  }
540  }
541  else
542  {
543  nulledForceTorqueRef = nullptr;
544  }
545  // Eigen::Vector3f filteredTargetVelocityVec;
546  // for (int i = 0; i < 3; ++i)
547  // {
548  // targetVelocityFilter.at(i).update(now.toMicroSeconds(), new Variant(targetVelocityVec(i)));
549  // filteredTargetVelocityVec(i) = targetVelocityFilter.at(i).getValue()->getFloat();
550  // }
551  // ARMARX_INFO << deactivateSpam(1) << VAROUT(*targetPositioninRootFrame) << VAROUT(*lwristPosition) << VAROUT(*rwristPosition);
552  // ARMARX_INFO << deactivateSpam(1) << VAROUT(distanceToTarget) << VAROUT(targetVelocityVec);
553  // Eigen::AngleAxisf aaOriErr(targetOrientation->toEigenQuaternion() * Eigen::Quaternionf(tcp->getPoseInRootFrame().block<3,3>(0,0)).inverse());
554  // Eigen::Vector3f angleVel = aaOriErr.axis() * VirtualRobot::MathTools::angleModPI(aaOriErr.angle());
555  // angleVel *= in.getKpOrientation();
556 
557  Eigen::VectorXf cv = posController.calculate(
558  Pose(targetOrientation->toEigen(), targetPositioninRootFrame->toEigen()).toEigen(),
559  VirtualRobot::IKSolver::All);
560  ctrl->setTargetVelocity(cv(0), cv(1), cv(2), cv(3), cv(4), cv(5));
561 
562 
563  // targetVelocity = new FramedDirection(filteredTargetVelocityVec, robot->getRootNode()->getName(), robot->getName());
564  // getTcpControlUnit()->setTCPVelocity(kinematicChainName, "", targetVelocity, nullptr);
565 
566  // ctrl->setTargetVelocity(targetVelocityVec(0),
567  // targetVelocityVec(1),
568  // targetVelocityVec(2),
569  // angleVel(0), angleVel(1), angleVel(2));
570 
571  arviz.commit({vizLayer});
572  cycle.waitForCycleDuration();
573  }
574  ctrl->deactivateAndDeleteController();
575  // c->getOpenPoseEstimation()->stop();
576  // usleep(100000);
577  // c->getOpenPoseEstimation()->stop();
578 
579  if (in.isObjectIDSet() && in.getObjectID().find("/") != std::string::npos)
580  {
581  objpose::DetachObjectFromRobotNodeInput input;
582  input.objectID = toIce(armarx::ObjectID(in.getObjectID()));
583  ARMARX_IMPORTANT << "Detaching object '" << input.objectID << "' in ObjectPoseStorage.";
584  objpose::DetachObjectFromRobotNodeOutput result =
585  getObjectPoseStorage()->detachObjectFromRobotNode(input);
586  (void)result;
587  }
588  else if (in.isObjectIDSet())
589  {
590  ARMARX_IMPORTANT << "Not detaching object '" << in.getObjectID()
591  << " because it does not look like an ObjectID.";
592  }
593  else
594  {
596  << "Not detaching object in ObjectPoseStorage because 'ObjectID' is not set.";
597  }
598 }
599 
600 //void ReachOutToHumanPose::onBreak()
601 //{
602 // // put your user code for the breaking point here
603 // // execution time should be short (<100ms)
604 //}
605 
606 void
607 ReachOutToHumanPose::onExit()
608 {
609  // put your user code for the exit point here
610  // execution time should be short (<100ms)
611 #if ENABLE_DEBUG_DRAWER
612  getDebugDrawerTopic()->removeLayer("HandOverState");
613 #endif
614  if (in.getStopOpenPoseAfterRun())
615  {
616  ARMARX_INFO << "Stopping OpenPose...";
617  getOpenPoseEstimation()->stop();
618  }
619  // getHeadIKUnit()->release();
620 
621  // FramedDirectionPtr targetVelocity = new FramedDirection(Eigen::Vector3f::Zero(), getLocalRobot()->getRootNode()->getName(), getLocalRobot()->getName());
622  // getTcpControlUnit()->setTCPVelocity(in.getKinematicChainName(), "", targetVelocity, targetVelocity);
623 }
624 
625 Eigen::Vector3f
626 ReachOutToHumanPose::getHeadIKTarget(const Keypoint3DMap& keypointMap)
627 {
628  //LAnkle -- -510.596 -1043.04 3889 0.267718
629  //LEar -- 0 0 0 0
630  //LElbow -- 0 0 0 0
631  //LEye -- 0 0 0 0
632  //LHip -- -657.189 -1591.2 3889 0.0951842
633  //LKnee -- -556.669 -1228.13 3604 0.281559
634  //LShoulder -- 0 0 0 0
635  //LWrist -- 0 0 0 0
636  //Neck -- 0 0 0 0
637  //Nose -- 0 0 0 0
638  //RAnkle -- 0 0 0 0
639  //REar -- 0 0 0 0
640  //RElbow -- 0 0 0 0
641  //REye -- 0 0 0 0
642  //RHip -- 0 0 0 0
643  //RKnee -- 0 0 0 0
644  //RShoulder -- 0 0 0 0
645  //RWrist -- 0 0 0 0
646 
647  std::vector<std::pair<std::string, float>> keypointPriorityOrderWithOffset = {
648  {"Neck", 20},
649  {"RShoulder", 20},
650  {"LShoulder", 20},
651  {"Nose", 0},
652  {"RElbow", 300},
653  {"LElbow", 300},
654  {"RWrist", 500},
655  {"LWrist", 500},
656  {"LHip", 600},
657  {"RHip", 600},
658  {"RKnee", 1100},
659  {"LKnee", 1100},
660  };
661  for (auto& pair : keypointPriorityOrderWithOffset)
662  {
663  auto it = keypointMap.find(pair.first);
664  if (it != keypointMap.end() && isKeypointValid(it->second))
665  {
666  ARMARX_INFO << "Selected node for head ik target is: " << it->first
667  << deactivateSpam(3, it->first);
668  Eigen::Vector3f result(it->second.x, it->second.y - pair.second, it->second.z);
669  return result;
670  }
671  }
672 
673  return Eigen::Vector3f::Zero();
674 }
675 
676 Eigen::VectorXf
677 ReachOutToHumanPose::calculateMedian(const Keypoint3DMap& keypointMap)
678 {
679  if (keypointMap.empty())
680  {
681  return Eigen::Vector3f::Zero();
682  }
683  Eigen::MatrixXf keypointPositions(keypointMap.size(), 3);
684  std::vector<std::vector<float>> values(3, Ice::FloatSeq(keypointMap.size(), 0.0));
685  int i = 0;
686  for (auto& pair : keypointMap)
687  {
688  values.at(0).at(i) = pair.second.x;
689  values.at(1).at(i) = pair.second.y;
690  values.at(2).at(i) = pair.second.z;
691  i++;
692  }
693 
694  std::sort(values.at(0).begin(), values.at(0).end());
695  std::sort(values.at(1).begin(), values.at(1).end());
696  std::sort(values.at(2).begin(), values.at(2).end());
697 
698  size_t center = keypointMap.size() / 2;
699  return Eigen::Vector3f(
700  values.at(0).at(center), values.at(1).at(center), values.at(2).at(center));
701 }
702 
703 Eigen::VectorXf
704 ReachOutToHumanPose::calculateCentroid(const Keypoint3DMap& keypointMap)
705 {
706  Eigen::MatrixXf keypointPositions(keypointMap.size(), 3);
707  int i = 0;
708  for (auto& pair : keypointMap)
709  {
710  keypointPositions(i, 0) = pair.second.x;
711  keypointPositions(i, 1) = pair.second.y;
712  keypointPositions(i, 2) = pair.second.z;
713  i++;
714  }
715  return keypointPositions.colwise().mean();
716 }
717 
718 Keypoint3DMap
719 ReachOutToHumanPose::getClosestPerson(const std::vector<Keypoint3DMap>& trackingData)
720 {
721  float minDistance = std::numeric_limits<float>::max();
722  Keypoint3DMap result;
723  for (auto& keypointMap : trackingData)
724  {
725  if (keypointMap.empty())
726  {
727  continue;
728  }
729  float distance = calculateMedian(keypointMap).norm();
730  if (distance < minDistance)
731  {
732  minDistance = distance;
733  result = keypointMap;
734  }
735  }
736  return result;
737 }
738 
739 bool
740 ReachOutToHumanPose::isKeypointValid(const Keypoint3D& point) const
741 {
742  if (point.confidence < in.getMinimumKeypointConfidence())
743  {
744  return false;
745  }
746  //if values directly at the camera -> not valid
747  return Eigen::Vector3f(point.x, point.y, point.z).norm() > 100;
748  // return !(point.x == 0.0f && point.y == 0.0f && point.z == 0.0f);
749 }
750 
751 // DO NOT EDIT NEXT FUNCTION
753 ReachOutToHumanPose::CreateInstance(XMLStateConstructorParams stateData)
754 {
755  return XMLStateFactoryBasePtr(new ReachOutToHumanPose(stateData));
756 }
Client.h
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:223
armarx::viz::Client::commit
CommitResult commit(StagedCommit const &commit)
Definition: Client.cpp:89
TIMING_START
#define TIMING_START(name)
Definition: TimeUtil.h:289
ice_conversions.h
armarx::ObjectID
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition: ObjectID.h:10
armarx::viz::Cylinder::radius
Cylinder & radius(float r)
Definition: Elements.h:76
TIMING_END
#define TIMING_END(name)
Definition: TimeUtil.h:306
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::RemoteRobot::synchronizeLocalClone
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
Definition: RemoteRobot.cpp:522
armarx::viz::Client::createFromTopic
static Client createFromTopic(std::string const &componentName, armarx::viz::Topic::ProxyType const &topic)
Definition: Client.cpp:40
Pose.h
armarx::MultiDimPIDControllerTemplate::update
void update(const double deltaSec, const PIDVectorX &measuredValue, const PIDVectorX &targetValue)
Definition: MultiDimPIDController.h:79
ScopedClient.h
armarx::TimeUtil::MSSleep
static void MSSleep(int durationMS)
lock the calling thread for a given duration (like usleep(...) but using Timeserver time)
Definition: TimeUtil.cpp:100
armarx::CartesianPositionController::maxPosVel
float maxPosVel
Definition: CartesianPositionController.h:82
armarx::MultiDimPIDControllerTemplate<>
armarx::XMLStateConstructorParams
Definition: XMLState.h:49
armarx::CycleUtil
This util class helps with keeping a cycle time during a control cycle.
Definition: CycleUtil.h:40
ProsthesisInterface.values
values
Definition: ProsthesisInterface.py:190
RobotHand.h
armarx::viz::ScopedClient
viz::Client that will delete (clear) committed layers when destroyed.
Definition: ScopedClient.h:42
armarx::filters::PoseAverageFilter
Definition: PoseAverageFilter.h:33
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::RobotUnitModule::ControllerManagement::deleteNJointController
void deleteNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Queues the given NJointControllerBase for deletion.
Definition: RobotUnitModuleControllerManagement.cpp:494
armarx::filters::AverageFilter
The AverageFilter class provides a simple filter by calculating the average value of a window for dat...
Definition: AverageFilter.h:42
armarx::viz::Layer::add
void add(ElementT const &element)
Definition: Layer.h:31
armarx::RobotUnitModule::ControllerManagement::createNJointController
NJointControllerInterfacePrx createNJointController(const std::string &className, const std::string &instanceName, const NJointControllerConfigPtr &config, const Ice::Current &=Ice::emptyCurrent) override
Cretes a NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:176
armarx::viz::Sphere
Definition: Elements.h:133
armarx::getRobotUnit
RobotUnit * getRobotUnit(RobotUnitModule::ControllerManagement *cmngr)
Definition: NJointController.cpp:35
PoseMedianFilter.h
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:64
IceInternal::Handle< FramedDirection >
armarx::DatafieldFilter::update
void update(Ice::Long timestamp, const VariantBasePtr &value, const Ice::Current &c=Ice::emptyCurrent) override
Adds the given value to the data map, erases old values if maximum size was reached,...
Definition: DatafieldFilter.cpp:41
armarx::toIce
void toIce(std::map< IceKeyT, IceValueT > &iceMap, const boost::container::flat_map< CppKeyT, CppValueT > &cppMap)
Definition: ice_conversions_boost_templates.h:15
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
DatafieldRef.h
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:281
ManagedIceObject.h
HandOverGroupStatechartContext.h
armarx::filters::PoseMedianFilter
The MedianFilter class provides an implementation for a median for datafields of type float,...
Definition: PoseMedianFilter.h:39
armarx::CartesianPositionController::KpOri
float KpOri
Definition: CartesianPositionController.h:81
ReachOutToHumanPose.h
armarx::viz::Cylinder
Definition: Elements.h:71
armarx::FramedPosition
The FramedPosition class.
Definition: FramedPose.h:157
armarx::viz::Sphere::radius
Sphere & radius(float r)
Definition: Elements.h:138
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:12
armarx::Vector3
The Vector3 class.
Definition: Pose.h:112
PoseAverageFilter.h
AverageFilter.h
timestamp
std::string timestamp()
Definition: CartographerAdapter.cpp:85
armarx::CycleUtil::waitForCycleDuration
IceUtil::Time waitForCycleDuration()
This function will wait (virtual or system time) until the cycle time is reached.
Definition: CycleUtil.cpp:53
max
T max(T t1, T t2)
Definition: gdiam.h:51
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::red
QColor red()
Definition: StyleSheets.h:78
armarx::DatafieldFilter::getValue
VariantBasePtr getValue(const Ice::Current &c=Ice::emptyCurrent) const override
Retrieves the current, filtered value.
Definition: DatafieldFilter.cpp:68
armarx::HandOverGroupStatechartContextExtension
Definition: HandOverGroupStatechartContext.h:49
CartesianPositionController.h
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
CycleUtil.h
PIDController.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::NJointTaskSpaceDMPControllerMode::eAll
@ eAll
Definition: ControllerInterface.ice:38
armarx::FramedDirection
FramedDirection is a 3 dimensional direction vector with a reference frame. The reference frame can b...
Definition: FramedPose.h:86
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::MultiDimPIDControllerTemplate::getControlValue
const PIDVectorX & getControlValue() const
Definition: MultiDimPIDController.h:201
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::viz::ElementOps::color
DerivedT & color(Color color)
Definition: ElementOps.h:218
armarx::RemoteRobot::synchronizeLocalCloneToTimestamp
static bool synchronizeLocalCloneToTimestamp(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx, Ice::Long timestamp)
Synchronizes a local robot to a robot state at timestamp.
Definition: RemoteRobot.cpp:566
armarx::view_selection::skills::direction::state::center
state::Type center(state::Type previous)
Definition: LookDirection.cpp:233
memoryx::KBM::Vector3
Eigen::Vector3d Vector3
Definition: kbm.h:43
armarx::CartesianPositionController
Definition: CartesianPositionController.h:42
distance
double distance(const Point &a, const Point &b)
Definition: point.hpp:95
armarx::CartesianPositionController::maxOriVel
float maxOriVel
Definition: CartesianPositionController.h:83
cv
Definition: helper.h:34
armarx::HandOverGroup::ReachOutToHumanPose
Definition: ReachOutToHumanPose.h:32
armarx::viz::ScopedClient::layer
Layer layer(std::string const &name) const
Definition: ScopedClient.cpp:34
armarx::CartesianPositionController::KpPos
float KpPos
Definition: CartesianPositionController.h:80
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:38
armarx::viz::Layer
Definition: Layer.h:12
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::DataFieldIdentifier
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
Definition: DataFieldIdentifier.h:48
armarx::green
QColor green()
Definition: StyleSheets.h:72
norm
double norm(const Point &a)
Definition: point.hpp:102
armarx::CartesianPositionController::calculate
Eigen::VectorXf calculate(const Eigen::Matrix4f &targetPose, VirtualRobot::IKSolver::CartesianSelection mode) const
Definition: CartesianPositionController.cpp:45