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