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"
25 
27 
28 //#include <ArmarXCore/core/time/TimeUtil.h>
32 
33 #include <RobotAPI/interface/units/RobotUnit/NJointCartesianVelocityControllerWithRamp.h>
34 
41 
45 
46 
47 using namespace armarx;
48 using namespace visionx;
49 using namespace HandOverGroup;
50 
51 // DO NOT EDIT NEXT LINE
52 ReachOutToHumanPose::SubClassRegistry ReachOutToHumanPose::Registry(ReachOutToHumanPose::GetName(), &ReachOutToHumanPose::CreateInstance);
53 
54 #define ENABLE_DEBUG_DRAWER 0
55 
56 
57 void ReachOutToHumanPose::onEnter()
58 {
59  // put your user code for the enter-point here
60  // execution time should be short (<100ms)
61  // ManagedIceObjectPtr obj = ManagedIceObjectPtr::dynamicCast(getContext());
62  // obj->getIceManager()->subscribeTopic()
63 }
64 
65 void ReachOutToHumanPose::run()
66 {
67  viz::ScopedClient arviz = viz::Client::createFromTopic("ReachOutToHumanPose", getArvizTopic());
68  arviz.commit({arviz.layer("HandOverState")}); // Clear layer.
69 
70  HandOverGroupStatechartContextExtension* c = getContext<HandOverGroupStatechartContextExtension>();
71  c->getOpenPoseEstimation()->start3DPoseEstimation();
72 
74  CycleUtil cycle(10);
75  filters::PoseMedianFilter lwristFilter(in.getPoseMedianFilterSize()), rwristFilter(in.getPoseMedianFilterSize());
76  filters::PoseAverageFilter headIKTargetFilter(50);
77  std::vector<filters::AverageFilter> targetPositionFilter(3), targetVelocityFilter(3);
78  for (auto& filter : targetPositionFilter)
79  {
80  filter.windowFilterSize = in.getTargetPositionAverageFilterSize();
81  }
82  for (auto& filter : targetVelocityFilter)
83  {
84  filter.windowFilterSize = in.getTargetPositionAverageFilterSize();
85  }
86  float maxTCPVelocity = in.getMaxTCPVelocity();
87  float considerForceDistanceThreshold = in.getConsiderForceDistanceThreshold();
88  auto robot = getLocalRobot();
89  auto cameraRobot = getLocalRobot(); // receives new copy
90  ARMARX_CHECK_EXPRESSION(robot.get() != cameraRobot.get());
91  filters::AverageFilter forceMagnitudeAvgFilter;
92  forceMagnitudeAvgFilter.windowFilterSize = 10;
93 
94  getHeadIKUnit()->request();
95 
96  // look straight ahead
97  ARMARX_INFO << "InitialHeadIKTarget(): " << in.getInitialHeadIKTarget()->output();
98  getHeadIKUnit()->setHeadTarget(in.getHeadIKNodeSet(), in.getInitialHeadIKTarget());
99  TimeUtil::MSSleep(1000);
100 
101  auto kinematicChainName = in.getKinematicChainName();
102  MultiDimPIDController pid(in.getKp(), 0, 0);
103  IceUtil::Time lastTimestamp = armarx::TimeUtil::GetTime();
105  auto nodeset = robot->getRobotNodeSet(kinematicChainName);
106  auto tcp = nodeset->getTCP();
107  auto kinematicRootName = nodeset->getKinematicRoot()->getName();
108 
109  ARMARX_INFO << VAROUT(kinematicRootName) << " position in root: " << nodeset->getKinematicRoot()->getPositionInRootFrame();
110  FramedDirectionPtr targetVelocity;
111  DatafieldRefPtr forceTorqueRef = DatafieldRefPtr::dynamicCast(getForceTorqueObserver()->getDataFieldRef(new DataFieldIdentifier(getForceTorqueObserver()->getObserverName(),
112  in.getFTSensorName(), "forces")));
113  ARMARX_CHECK_EXPRESSION(forceTorqueRef);
114  DatafieldRefPtr nulledForceTorqueRef;
115  NJointCartesianVelocityControllerWithRampConfigPtr ctrlCfg = new NJointCartesianVelocityControllerWithRampConfig();
116  ctrlCfg->KpJointLimitAvoidance = 0;
117  ctrlCfg->jointLimitAvoidanceScale = 1;
118  ctrlCfg->mode = CartesianSelectionMode::eAll;
119  ctrlCfg->nodeSetName = kinematicChainName;
120  ctrlCfg->tcpName = tcp->getName();
121  ctrlCfg->maxNullspaceAcceleration = 2;
122  ctrlCfg->maxPositionAcceleration = in.getTCPAcceleration();
123  ctrlCfg->maxOrientationAcceleration = 1;
124 
125  CartesianPositionController posController(tcp);
126  posController.maxOriVel = in.getMaxOrientationVelocity();
127  posController.maxPosVel = in.getMaxTCPVelocity();
128  posController.KpOri = in.getKpOrientation();
129  posController.KpPos = in.getKp();
130 
131  auto ctrlName = "ReachOutToHumanTCPCtrl";
132  TIMING_START(NJointCtrlCreation);
133  ARMARX_INFO << deactivateSpam(1) << "Getting old controller";
134  if (auto oldCtrl = getRobotUnit()->getNJointController(ctrlName))
135  {
136  ARMARX_INFO << deactivateSpam(1) << "got old controller";
137  while (oldCtrl->isControllerActive())
138  {
139  oldCtrl->deactivateController();
140  ARMARX_INFO << deactivateSpam(1) << "Waiting for old controller to be deactivated";
141  usleep(30000);
142  }
143  ARMARX_INFO << deactivateSpam(1) << "deleting old controller";
145  usleep(100000);
146  }
147  ARMARX_INFO << deactivateSpam(1) << "Getting new controller";
148  auto baseCtrl = getRobotUnit()->createNJointController("NJointCartesianVelocityControllerWithRamp", ctrlName, ctrlCfg);
149  ARMARX_CHECK_EXPRESSION(baseCtrl);
150  NJointCartesianVelocityControllerWithRampInterfacePrx ctrl = NJointCartesianVelocityControllerWithRampInterfacePrx::checkedCast(baseCtrl);
151  TIMING_END(NJointCtrlCreation);
152  ARMARX_CHECK_EXPRESSION(ctrl) << baseCtrl->ice_ids();
153  ctrl->activateController();
154 
155  auto targetOrientation = in.getHandOrientation();
156  IceUtil::Time startTime = TimeUtil::GetTime();
157 
158  RemoteRobot::synchronizeLocalClone(robot, getRobotStateComponent());
159 
160  const Eigen::Vector3f offset {0, 0, 300};
161  Eigen::Vector3f idlePosi = tcp->getPositionInRootFrame() + offset;
162  FramedPositionPtr idlePosition = new FramedPosition(
163  idlePosi, robot->getRootNode()->getName(), robot->getName());
164  // in.getIdlePosition();
165 
166  bool drawDebugInfos = in.getDrawDebugInfos();
167  FramedPositionPtr lastIKTarget;
168  while (!isRunningTaskStopped()) // stop run function if returning true
169  {
170  viz::Layer vizLayer = arviz.layer("HandOverState");
171 
172  auto now = armarx::TimeUtil::GetTime();
173  auto timeSinceSinceStart = now - startTime;
174  IceUtil::Time duration = now - lastTimestamp;
175  lastTimestamp = now;
176 
177  c->getImageSourceSelectionTopic()->setImageSource("OpenPoseEstimationResult", 5000);
178 
179  // do your calculations
180  std::vector<Keypoint3DMap> keypointList;
181  IceUtil::Time timestamp;
182  std::tie(timestamp, keypointList) = c->getPoseData()->getLatestData();
183  RemoteRobot::synchronizeLocalClone(robot, getRobotStateComponent());
184  RemoteRobot::synchronizeLocalCloneToTimestamp(cameraRobot, getRobotStateComponent(), timestamp.toMicroSeconds());
185 
186  Keypoint3DMap poseData = getClosestPerson(keypointList);
187  int validKeypoints = 0;
188  for (auto& pair : poseData)
189  {
190  if (isKeypointValid(pair.second))
191  {
192  validKeypoints++;
193  }
194  }
195 
196 
197  Keypoint3D rwrist = poseData["RWrist"];
198  Vector3Ptr rwristPosition = new Vector3(rwrist.x, rwrist.y, rwrist.z);
199  bool validTarget = false;
200  if (isKeypointValid(rwrist))
201  {
202  rwristFilter.update(now.toMicroSeconds(), new Variant(rwristPosition));
203  }
204  auto tmp = rwristFilter.getValue();
205  if (tmp)
206  {
207  Vector3Ptr filteredRWristPosition = VariantPtr::dynamicCast(tmp)->get<Vector3>();
208  ARMARX_CHECK_EXPRESSION(filteredRWristPosition);
209  FramedPositionPtr globalrWristPosition = FramedPosition(filteredRWristPosition->toEigen(), in.getCameraFrameName(), robot->getName()).toGlobal(robot);
210  // ARMARX_INFO << deactivateSpam(1) << VAROUT(*globalrWristPosition);
211  if (drawDebugInfos)
212  {
213 #if ENABLE_DEBUG_DRAWER
214  this->getDebugDrawerTopic()->setSphereVisu("HandOverState", "rwrist", globalrWristPosition, DrawColor {1.0f, 0.0f, 0.0f, rwrist.confidence}, 30);
215 #else
216  vizLayer.add(viz::Sphere("rwrist")
217  .position(globalrWristPosition->toEigen())
218  .color(simox::Color::red(255, 255 * rwrist.confidence))
219  .radius(30));
220 #endif
221  getDebugObserver()->setDebugChannel(
222  "HandOverState",
223  {
224  { "rwristpoint_z", new Variant(rwristPosition->z) },
225  { "rwristpoint_z_filtered", new Variant(filteredRWristPosition->z) },
226  });
227  }
228 
229  rwristPosition = filteredRWristPosition;
230  validTarget = true;
231  }
232  Keypoint3D lwrist = poseData["LWrist"];
233  Vector3Ptr lwristPosition = new Vector3(lwrist.x, lwrist.y, lwrist.z);
234  if (isKeypointValid(lwrist))
235  {
236  lwristFilter.update(now.toMicroSeconds(), new Variant(lwristPosition));
237  }
238  tmp = lwristFilter.getValue();
239  if (tmp)
240  {
241  lwristPosition = VariantPtr::dynamicCast(tmp)->get<Vector3>();
242  ARMARX_CHECK_EXPRESSION(lwristPosition);
243  FramedPositionPtr globallWristPosition = FramedPosition(lwristPosition->toEigen(), in.getCameraFrameName(), robot->getName()).toGlobal(robot);
244  // ARMARX_INFO << deactivateSpam(1) << VAROUT(*globallWristPosition) << VAROUT(robot->getGlobalPose());
245  if (drawDebugInfos)
246  {
247 #if ENABLE_DEBUG_DRAWER
248  this->getDebugDrawerTopic()->setSphereVisu("HandOverState", "lwrist", globallWristPosition, DrawColor {0.0f, 1.0f, 0.0f, lwrist.confidence}, 30);
249 #else
250  vizLayer.add(viz::Sphere("lwrist")
251  .position(globallWristPosition->toEigen())
252  .color(simox::Color::green(255, 255 * lwrist.confidence))
253  .radius(30));
254 #endif
255  }
256  validTarget = true;
257  }
258  // ARMARX_INFO << deactivateSpam(1) << "Filtered wrist data";
259  float leftHandDistance = lwristPosition && isKeypointValid(lwrist) ? lwristPosition->toEigen().norm() : std::numeric_limits<float>::max();
260  float rightHandDistance = rwristPosition && isKeypointValid(rwrist) ? rwristPosition->toEigen().norm() : std::numeric_limits<float>::max();
261 
262  Vector3Ptr currentHandPosition = leftHandDistance < rightHandDistance ? lwristPosition : rwristPosition;
263 
264  if (drawDebugInfos)
265  {
266  getDebugObserver()->setDebugChannel(
267  "ReachOutToHuman",
268  {
269  { "zDiffLShoulder", new Variant(std::abs(poseData["LWrist"].z - poseData["LShoulder"].z)) },
270  { "zDiffNeckR", new Variant(std::abs(poseData["RWrist"].z - poseData["Neck"].z)) },
271  { "zDiffNeckL", new Variant(std::abs(poseData["LWrist"].z - poseData["Neck"].z)) }
272  });
273  }
274 
275 
276  Eigen::Vector3f headIkTarget = getHeadIKTarget(poseData);
277  FramedPositionPtr globalHeadIkTarget = FramedPosition(headIkTarget, in.getCameraFrameName(), robot->getName()).toGlobal(cameraRobot);
278  globalHeadIkTarget->z = std::max(in.getMinimumGazeZPosition(), globalHeadIkTarget->z);
279 
280  if (validKeypoints > 3 && !in.getHeadIKNodeSet().empty() && headIkTarget.norm() > 0)
281  {
282  if (drawDebugInfos)
283  {
284 #if ENABLE_DEBUG_DRAWER
285  this->getDebugDrawerTopic()->setSphereVisu("HandOverState", "Median", globalHeadIkTarget, DrawColor {1.0f, 1.0f, 0.0f, 1.0f}, 50);
286 #else
287  vizLayer.add(viz::Sphere("Median")
288  .position(globalHeadIkTarget->toEigen())
289  .color(simox::Color::yellow())
290  .radius(50));
291 #endif
292  }
293  headIKTargetFilter.update(now.toMicroSeconds(), new Variant(globalHeadIkTarget));
294  auto tmp = headIKTargetFilter.getValue();
296  FramedPositionPtr globalFilteredMedianKeypoint = VariantPtr::dynamicCast(tmp)->get<FramedPosition>();
297  ARMARX_CHECK_EXPRESSION(globalFilteredMedianKeypoint);
298  if ((TimeUtil::GetTime() - startTime).toSecondsDouble() > 1.3)
299  {
300  if (!lastIKTarget || (lastIKTarget->toEigen() - globalFilteredMedianKeypoint->toEigen()).norm() > 100)
301  {
302  getHeadIKUnit()->setHeadTarget(in.getHeadIKNodeSet(), globalFilteredMedianKeypoint);
303  lastIKTarget = globalFilteredMedianKeypoint;
304  // ARMARX_INFO << deactivateSpam(1) << "HeadIK Target: " << *globalFilteredMedianKeypoint;
305  }
306  }
307  }
308  else
309  {
310 #if ENABLE_DEBUG_DRAWER
311  this->getDebugDrawerTopic()->removeSphereVisu("HandOverState", "Median");
312 #else
313  // Don't add Median to the layer.
314 #endif
315  }
316 
317 
318  float currentHumanReachDistance = headIkTarget.norm() == 0 && currentHandPosition->toEigen().norm() > 100 ? 0 : std::abs((currentHandPosition->toEigen() - headIkTarget)(2));
319  bool humanIsReachingOut = currentHumanReachDistance > in.getHumanMinimumReachOutDistance();
320  // ARMARX_INFO << deactivateSpam(1) << VAROUT(currentHumanReachDistance) << VAROUT(humanIsReachingOut);
321  Eigen::Vector3f currentTargetVec = currentHandPosition->toEigen();
322  for (int i = 0; i < 3; ++i)
323  {
324  targetPositionFilter.at(i).update(now.toMicroSeconds(), new Variant(currentTargetVec(i)));
325  }
326  Eigen::Vector3f currentFilteredTargetPositionVec;
327  for (int i = 0; i < 3; ++i)
328  {
329  currentFilteredTargetPositionVec(i) = targetPositionFilter.at(i).getValue()->getFloat();
330  }
331  // ARMARX_INFO << deactivateSpam(1) << "Filtered target position ";
332  FramedPositionPtr targetPositioninRootFrame = new FramedPosition(currentFilteredTargetPositionVec, in.getCameraFrameName(), cameraRobot->getName());
333  targetPositioninRootFrame->changeFrame(robot, robot->getRootNode()->getName());
334 
335  // FramedPositionPtr localFramedPosition;
337  // float currentReachDistance = tcp->getTransformationFrom(nodeset->getKinematicRoot()).block<3,1>(0,3).norm();
338  FramedPositionPtr targetInKinematicRootFrame = new FramedPosition(*targetPositioninRootFrame);
339  targetInKinematicRootFrame->changeFrame(robot, kinematicRootName);
340  float reachDistanceToTarget = targetInKinematicRootFrame->toEigen().norm();
341  ARMARX_INFO << deactivateSpam(1) << VAROUT(reachDistanceToTarget);
342  getDebugObserver()->setDebugDatafield("ReachOutToHuman", "reachDistanceToTarget", new Variant(reachDistanceToTarget));
343  float reachDistanceToTargetClamped = reachDistanceToTarget;
344  if (reachDistanceToTarget > in.getDistanceThresholdSoft() && reachDistanceToTarget < in.getDistanceThreshold())
345  {
346  Eigen::Vector3f targetPositioninKinematicRootFrameClamped = targetInKinematicRootFrame->toEigen().normalized() * in.getDistanceThresholdSoft();
347  targetPositioninRootFrame = new FramedPosition(targetPositioninKinematicRootFrameClamped, targetInKinematicRootFrame->frame,
348  targetInKinematicRootFrame->agent);
349  targetPositioninRootFrame->changeFrame(robot, robot->getRootNode()->getName());
350  reachDistanceToTargetClamped = targetPositioninKinematicRootFrameClamped.norm();
351 
352  }
353  if (drawDebugInfos)
354  {
355  getDebugObserver()->setDebugChannel(
356  "ReachOutToHuman",
357  {
358  { "targetPositioninRootFrameX", new Variant(targetPositioninRootFrame->x) },
359  { "targetPositioninRootFrameY", new Variant(targetPositioninRootFrame->y) },
360  { "targetPositioninRootFrameZ", new Variant(targetPositioninRootFrame->z) },
361  { "targetPositioninRootNorm", new Variant(targetPositioninRootFrame->toEigen().norm()) },
362  { "reachDistanceToTargetClamped", new Variant(reachDistanceToTargetClamped) }
363  });
364  }
365 
366  float distanceToTarget = (tcp->getPositionInRootFrame() - targetPositioninRootFrame->toEigen()).norm();
367 
368  bool returnToIdlePose = reachDistanceToTarget > in.getDistanceThreshold() || !validTarget || !humanIsReachingOut || validKeypoints < 5 || timeSinceSinceStart.toMilliSeconds() < in.getMinWaitBeforeReachTime();
369  if (returnToIdlePose)
370  {
371  targetPositioninRootFrame = in.getIdlePosition();
372  }
373  else
374  {
375  idlePosition = in.getIdlePosition();
376  targetPositioninRootFrame->y -= in.getTargetYOffset();
377  }
378  // ARMARX_CHECK_EXPRESSION(lwristPosition);
379  // ARMARX_CHECK_EXPRESSION(lwristPosition);
380  ARMARX_CHECK_EXPRESSION(lwristPosition);
381 
382  FramedPositionPtr globalTargetPosition = targetPositioninRootFrame->toGlobal(robot);
383  if (drawDebugInfos)
384  {
385 #if ENABLE_DEBUG_DRAWER
386  getDebugDrawerTopic()->setSphereVisu("HandOverState", "TargetPosition", globalTargetPosition, DrawColor {0.0f, 1.0f, 1.0f, 1.0}, 30);
387  getDebugDrawerTopic()->setLineVisu("HandOverState", "ReachOutLine", globalTargetPosition, globalHeadIkTarget, 5,
388  humanIsReachingOut ? DrawColor {0.0f, 1.0f, 0.0f, 1.0} : DrawColor {1.0f, 0, 0, 1.0});
389 #else
390  vizLayer.add(viz::Sphere("TargetPosition")
391  .position(globalTargetPosition->toEigen())
392  .color(simox::Color::cyan())
393  .radius(30));
394  vizLayer.add(viz::Cylinder("ReachOutLine").fromTo(globalTargetPosition->toEigen(), globalHeadIkTarget->toEigen())
395  .radius(5).color(humanIsReachingOut ? simox::Color::green() : simox::Color::red()));
396 #endif
397  }
398 
399 
400  pid.update(duration.toMicroSecondsDouble(), tcp->getPositionInRootFrame(), targetPositioninRootFrame->toEigen());
401  Eigen::Vector3f targetVelocityVec = pid.getControlValue();
402  if (targetVelocityVec.norm() > maxTCPVelocity)
403  {
404  targetVelocityVec = targetVelocityVec.normalized() * maxTCPVelocity;
405  }
406  if (distanceToTarget < considerForceDistanceThreshold)
407  {
408  targetVelocityVec = Eigen::Vector3f::Zero();
409  if (!nulledForceTorqueRef)
410  {
411  nulledForceTorqueRef = DatafieldRefPtr::dynamicCast(getForceTorqueObserver()->createNulledDatafield(forceTorqueRef));
412  }
413  FramedDirectionPtr nulledFT = nulledForceTorqueRef->getDataField()->get<FramedDirection>();
414  float forceMagnitude = nulledFT->toEigen().norm();
415  if (drawDebugInfos)
416  {
417  getDebugObserver()->setDebugChannel(
418  "ReachOutToHuman",
419  {
420  { "ForceX", new Variant(nulledFT->x) },
421  { "ForceZ", new Variant(nulledFT->z) },
422  { "ForceMagnitude", new Variant(forceMagnitude) }
423  }
424  );
425  }
426  forceMagnitudeAvgFilter.update(now.toMicroSeconds(), new Variant(forceMagnitude));
427  float forceMagnitudeFiltered = forceMagnitudeAvgFilter.getValue()->getFloat();
428  if (drawDebugInfos)
429  {
430  getDebugObserver()->setDebugDatafield("ReachOutToHuman", "forceMagnitudeFiltered", new Variant(forceMagnitudeFiltered));
431  }
432 
433  ARMARX_INFO << deactivateSpam(1) << VAROUT(forceMagnitude) << " threshold: " << in.getForceThreshold();
434  if (forceMagnitude > in.getForceThreshold())
435  {
436  ARMARX_IMPORTANT << "ForceThresholdReached: " << forceMagnitude;
437  this->emitForceThresholdReached();
438  break;
439  }
440  }
441  else
442  {
443  nulledForceTorqueRef = nullptr;
444  }
445  // Eigen::Vector3f filteredTargetVelocityVec;
446  // for (int i = 0; i < 3; ++i)
447  // {
448  // targetVelocityFilter.at(i).update(now.toMicroSeconds(), new Variant(targetVelocityVec(i)));
449  // filteredTargetVelocityVec(i) = targetVelocityFilter.at(i).getValue()->getFloat();
450  // }
451  // ARMARX_INFO << deactivateSpam(1) << VAROUT(*targetPositioninRootFrame) << VAROUT(*lwristPosition) << VAROUT(*rwristPosition);
452  // ARMARX_INFO << deactivateSpam(1) << VAROUT(distanceToTarget) << VAROUT(targetVelocityVec);
453  // Eigen::AngleAxisf aaOriErr(targetOrientation->toEigenQuaternion() * Eigen::Quaternionf(tcp->getPoseInRootFrame().block<3,3>(0,0)).inverse());
454  // Eigen::Vector3f angleVel = aaOriErr.axis() * VirtualRobot::MathTools::angleModPI(aaOriErr.angle());
455  // angleVel *= in.getKpOrientation();
456 
457  Eigen::VectorXf cv = posController.calculate(Pose(targetOrientation->toEigen(), targetPositioninRootFrame->toEigen()).toEigen(), VirtualRobot::IKSolver::All);
458  ctrl->setTargetVelocity(cv(0), cv(1), cv(2), cv(3), cv(4), cv(5));
459 
460 
461  // targetVelocity = new FramedDirection(filteredTargetVelocityVec, robot->getRootNode()->getName(), robot->getName());
462  // getTcpControlUnit()->setTCPVelocity(kinematicChainName, "", targetVelocity, nullptr);
463 
464  // ctrl->setTargetVelocity(targetVelocityVec(0),
465  // targetVelocityVec(1),
466  // targetVelocityVec(2),
467  // angleVel(0), angleVel(1), angleVel(2));
468 
469  arviz.commit({vizLayer});
470  cycle.waitForCycleDuration();
471  }
472  ctrl->deactivateAndDeleteController();
473  // c->getOpenPoseEstimation()->stop();
474  // usleep(100000);
475  // c->getOpenPoseEstimation()->stop();
476 
477  if (in.isObjectIDSet() && in.getObjectID().find("/") != std::string::npos)
478  {
479  objpose::DetachObjectFromRobotNodeInput input;
480  input.objectID = toIce(armarx::ObjectID(in.getObjectID()));
481  ARMARX_IMPORTANT << "Detaching object '" << input.objectID << "' in ObjectPoseStorage.";
482  objpose::DetachObjectFromRobotNodeOutput result = getObjectPoseStorage()->detachObjectFromRobotNode(input);
483  (void) result;
484  }
485  else if (in.isObjectIDSet())
486  {
487  ARMARX_IMPORTANT << "Not detaching object '" << in.getObjectID() << " because it does not look like an ObjectID.";
488  }
489  else
490  {
491  ARMARX_IMPORTANT << "Not detaching object in ObjectPoseStorage because 'ObjectID' is not set.";
492  }
493 }
494 
495 //void ReachOutToHumanPose::onBreak()
496 //{
497 // // put your user code for the breaking point here
498 // // execution time should be short (<100ms)
499 //}
500 
501 void ReachOutToHumanPose::onExit()
502 {
503  // put your user code for the exit point here
504  // execution time should be short (<100ms)
505 #if ENABLE_DEBUG_DRAWER
506  getDebugDrawerTopic()->removeLayer("HandOverState");
507 #endif
508  if (in.getStopOpenPoseAfterRun())
509  {
510  ARMARX_INFO << "Stopping OpenPose...";
511  getOpenPoseEstimation()->stop();
512  }
513  // getHeadIKUnit()->release();
514 
515  // FramedDirectionPtr targetVelocity = new FramedDirection(Eigen::Vector3f::Zero(), getLocalRobot()->getRootNode()->getName(), getLocalRobot()->getName());
516  // getTcpControlUnit()->setTCPVelocity(in.getKinematicChainName(), "", targetVelocity, targetVelocity);
517 }
518 
519 Eigen::Vector3f ReachOutToHumanPose::getHeadIKTarget(const Keypoint3DMap& keypointMap)
520 {
521  //LAnkle -- -510.596 -1043.04 3889 0.267718
522  //LEar -- 0 0 0 0
523  //LElbow -- 0 0 0 0
524  //LEye -- 0 0 0 0
525  //LHip -- -657.189 -1591.2 3889 0.0951842
526  //LKnee -- -556.669 -1228.13 3604 0.281559
527  //LShoulder -- 0 0 0 0
528  //LWrist -- 0 0 0 0
529  //Neck -- 0 0 0 0
530  //Nose -- 0 0 0 0
531  //RAnkle -- 0 0 0 0
532  //REar -- 0 0 0 0
533  //RElbow -- 0 0 0 0
534  //REye -- 0 0 0 0
535  //RHip -- 0 0 0 0
536  //RKnee -- 0 0 0 0
537  //RShoulder -- 0 0 0 0
538  //RWrist -- 0 0 0 0
539 
540  std::vector<std::pair<std::string, float>> keypointPriorityOrderWithOffset =
541  {
542  {"Neck", 20}, {"RShoulder", 20}, {"LShoulder", 20}, {"Nose", 0}, {"RElbow", 300}, {"LElbow", 300},
543  {"RWrist", 500}, {"LWrist", 500}, {"LHip", 600}, {"RHip", 600}, {"RKnee", 1100}, {"LKnee", 1100},
544  };
545  for (auto& pair : keypointPriorityOrderWithOffset)
546  {
547  auto it = keypointMap.find(pair.first);
548  if (it != keypointMap.end() && isKeypointValid(it->second))
549  {
550  ARMARX_INFO << "Selected node for head ik target is: " << it->first << deactivateSpam(3, it->first);
551  Eigen::Vector3f result(it->second.x, it->second.y - pair.second, it->second.z);
552  return result;
553  }
554  }
555 
556  return Eigen::Vector3f::Zero();
557 }
558 
559 Eigen::VectorXf ReachOutToHumanPose::calculateMedian(const Keypoint3DMap& keypointMap)
560 {
561  if (keypointMap.empty())
562  {
563  return Eigen::Vector3f::Zero();
564  }
565  Eigen::MatrixXf keypointPositions(keypointMap.size(), 3);
566  std::vector<std::vector<float>> values(3, Ice::FloatSeq(keypointMap.size(), 0.0));
567  int i = 0;
568  for (auto& pair : keypointMap)
569  {
570  values.at(0).at(i) = pair.second.x;
571  values.at(1).at(i) = pair.second.y;
572  values.at(2).at(i) = pair.second.z;
573  i++;
574  }
575 
576  std::sort(values.at(0).begin(), values.at(0).end());
577  std::sort(values.at(1).begin(), values.at(1).end());
578  std::sort(values.at(2).begin(), values.at(2).end());
579 
580  size_t center = keypointMap.size() / 2;
581  return Eigen::Vector3f(values.at(0).at(center),
582  values.at(1).at(center),
583  values.at(2).at(center));
584 }
585 
586 Eigen::VectorXf ReachOutToHumanPose::calculateCentroid(const Keypoint3DMap& keypointMap)
587 {
588  Eigen::MatrixXf keypointPositions(keypointMap.size(), 3);
589  int i = 0;
590  for (auto& pair : keypointMap)
591  {
592  keypointPositions(i, 0) = pair.second.x;
593  keypointPositions(i, 1) = pair.second.y;
594  keypointPositions(i, 2) = pair.second.z;
595  i++;
596  }
597  return keypointPositions.colwise().mean();
598 }
599 
600 Keypoint3DMap ReachOutToHumanPose::getClosestPerson(const std::vector<Keypoint3DMap>& trackingData)
601 {
602  float minDistance = std::numeric_limits<float>::max();
603  Keypoint3DMap result;
604  for (auto& keypointMap : trackingData)
605  {
606  if (keypointMap.empty())
607  {
608  continue;
609  }
610  float distance = calculateMedian(keypointMap).norm();
611  if (distance < minDistance)
612  {
613  minDistance = distance;
614  result = keypointMap;
615  }
616  }
617  return result;
618 }
619 
620 bool ReachOutToHumanPose::isKeypointValid(const Keypoint3D& point) const
621 {
622  if (point.confidence < in.getMinimumKeypointConfidence())
623  {
624  return false;
625  }
626  //if values directly at the camera -> not valid
627  return Eigen::Vector3f(point.x, point.y, point.z).norm() > 100;
628  // return !(point.x == 0.0f && point.y == 0.0f && point.z == 0.0f);
629 
630 }
631 
632 
633 // DO NOT EDIT NEXT FUNCTION
634 XMLStateFactoryBasePtr ReachOutToHumanPose::CreateInstance(XMLStateConstructorParams stateData)
635 {
636  return XMLStateFactoryBasePtr(new ReachOutToHumanPose(stateData));
637 }
638 
Client.h
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::viz::Client::commit
CommitResult commit(StagedCommit const &commit)
Definition: Client.cpp:80
TIMING_START
#define TIMING_START(name)
Definition: TimeUtil.h:280
ice_conversions.h
armarx::ObjectID
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition: ObjectID.h:11
armarx::viz::Cylinder::radius
Cylinder & radius(float r)
Definition: Elements.h:78
TIMING_END
#define TIMING_END(name)
Definition: TimeUtil.h:296
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
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:448
armarx::viz::Client::createFromTopic
static Client createFromTopic(std::string const &componentName, armarx::viz::Topic::ProxyType const &topic)
Definition: Client.cpp:36
Pose.h
armarx::MultiDimPIDControllerTemplate::update
void update(const double deltaSec, const PIDVectorX &measuredValue, const PIDVectorX &targetValue)
Definition: MultiDimPIDController.h:75
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:94
armarx::CartesianPositionController::maxPosVel
float maxPosVel
Definition: CartesianPositionController.h:76
armarx::MultiDimPIDControllerTemplate<>
armarx::XMLStateConstructorParams
Definition: XMLState.h:50
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:35
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
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:520
armarx::filters::AverageFilter
The AverageFilter class provides a simple filter by calculating the average value of a window for dat...
Definition: AverageFilter.h:41
armarx::viz::Layer::add
void add(ElementT const &element)
Definition: Layer.h:29
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:134
armarx::getRobotUnit
RobotUnit * getRobotUnit(RobotUnitModule::ControllerManagement *cmngr)
Definition: NJointController.cpp:35
PoseMedianFilter.h
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:44
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:72
DatafieldRef.h
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:253
ManagedIceObject.h
HandOverGroupStatechartContext.h
armarx::filters::PoseMedianFilter
The MedianFilter class provides an implementation for a median for datafields of type float,...
Definition: PoseMedianFilter.h:40
armarx::CartesianPositionController::KpOri
float KpOri
Definition: CartesianPositionController.h:75
ReachOutToHumanPose.h
armarx::viz::Cylinder
Definition: Elements.h:74
armarx::FramedPosition
The FramedPosition class.
Definition: FramedPose.h:142
armarx::viz::Sphere::radius
Sphere & radius(float r)
Definition: Elements.h:138
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:19
armarx::Vector3
The Vector3 class.
Definition: Pose.h:112
PoseAverageFilter.h
AverageFilter.h
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:48
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::red
QColor red()
Definition: StyleSheets.h:76
armarx::DatafieldFilter::getValue
VariantBasePtr getValue(const Ice::Current &c=Ice::emptyCurrent) const override
Retrieves the current, filtered value.
Definition: DatafieldFilter.cpp:70
armarx::HandOverGroupStatechartContextExtension
Definition: HandOverGroupStatechartContext.h:46
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::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:65
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:83
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::MultiDimPIDControllerTemplate::getControlValue
const PIDVectorX & getControlValue() const
Definition: MultiDimPIDController.h:186
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::viz::ElementOps::color
DerivedT & color(Color color)
Definition: ElementOps.h:195
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:487
memoryx::KBM::Vector3
Eigen::Vector3d Vector3
Definition: kbm.h:41
armarx::CartesianPositionController
Definition: CartesianPositionController.h:41
distance
double distance(const Point &a, const Point &b)
Definition: point.hpp:88
armarx::CartesianPositionController::maxOriVel
float maxOriVel
Definition: CartesianPositionController.h:77
cv
Definition: helper.h:35
armarx::HandOverGroup::ReachOutToHumanPose
Definition: ReachOutToHumanPose.h:30
armarx::viz::ScopedClient::layer
Layer layer(std::string const &name) const
Definition: ScopedClient.cpp:34
armarx::CartesianPositionController::KpPos
float KpPos
Definition: CartesianPositionController.h:74
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:39
armarx::viz::Layer
Definition: Layer.h:12
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
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:94
armarx::CartesianPositionController::calculate
Eigen::VectorXf calculate(const Eigen::Matrix4f &targetPose, VirtualRobot::IKSolver::CartesianSelection mode) const
Definition: CartesianPositionController.cpp:37