RobotGiver.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  * @author Fabian Reister ( fabian dot reister at kit dot edu )
17  * @date 2022
18  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19  * GNU General Public License
20  */
21 
22 #include "RobotGiver.h"
23 
24 #include <VirtualRobot/Robot.h>
25 
29 
33 
35 {
36  std::vector<gaze_targets::GazeTarget>
38  {
39  std::vector<gaze_targets::GazeTarget> targets;
40 
41  switch (phase_)
42  {
43  case Phase::PreHandover:
44  targets = updateTargetsPreHandover(human);
45  break;
47  targets = updateTargetsPreHandover(human);
48  break;
49  }
50 
51  return targets;
52  }
53 
54  std::vector<gaze_targets::GazeTarget>
55  RobotGiver::updateTargetsPreHandover(const armem::human::HumanPose& human) const
56  {
57 
58  const auto headKpName = util::headKeypoint(human.poseModelId);
59  const auto pelvisKpName = util::pelvisKeypoint(human.poseModelId);
60  const auto leftWristKpName = util::leftWristKeypoint(human.poseModelId);
61  const auto rightWristKpName = util::rightWristKeypoint(human.poseModelId);
62 
63  ARMARX_CHECK(headKpName.has_value());
64  ARMARX_CHECK(leftWristKpName.has_value());
65  ARMARX_CHECK(rightWristKpName.has_value());
66  ARMARX_CHECK(pelvisKpName.has_value());
67 
68  std::vector<gaze_targets::GazeTarget> gazeTargets;
69 
70  if (human.keypoints.count(headKpName.value()) == 0)
71  {
72  ARMARX_WARNING << deactivateSpam(1) << "Head keypoint `" << headKpName.value()
73  << "` not available!";
74  return {};
75  };
76 
77  // head target
78  {
79  const armem::human::PoseKeypoint headKp = human.keypoints.at(headKpName.value());
80 
81  const gaze_targets::TargetPriority targetPriority(
83 
84  gaze_targets::GazeTarget headTarget(
85  "head", headKp.positionGlobal.value(), targetPriority, Duration::Seconds(1), false);
86  gazeTargets.push_back(headTarget);
87  }
88 
89  const armem::human::PoseKeypoint pelvisKp = human.keypoints.at(pelvisKpName.value());
90 
91  const float distanceHumanRobot =
92  (pelvisKp.positionGlobal.value().toEigen() - robot_->getGlobalPosition())
93  .head<2>()
94  .norm();
95  ARMARX_VERBOSE << VAROUT(distanceHumanRobot);
96 
97  if (distanceHumanRobot > params.maxHandoverInitializationDistance)
98  {
99  return gazeTargets;
100  }
101 
102 
103  // the priority to look at the humans hands is defined by the distance to the pelvis (2d projection)
104 
105  const auto priorityFromDistance =
106  [&](const float handBodyDistance, const float handRobotDistance)
107  {
108  // f = 1: highest priority
109  // f = 0: low prio
110  const float normalizedHandBodyPriority =
111  std::clamp((handBodyDistance - params.minHandReachoutDistance) /
113  0.f,
114  1.f);
115 
116  const float normalizedHandRobotPriority = std::clamp(
117  (params.maxHandoverInitializationDistance - handRobotDistance) /
119  0.f,
120  1.f);
121 
122  return params.handPriorityScaling * normalizedHandBodyPriority *
123  normalizedHandRobotPriority;
124  };
125 
126  // left wrist target
127  if (human.keypoints.count(leftWristKpName.value()) > 0)
128  {
129  const armem::human::PoseKeypoint leftWristKp =
130  human.keypoints.at(leftWristKpName.value());
131 
132  const float distanceLeft =
133  (leftWristKp.positionGlobal->toEigen() - pelvisKp.positionGlobal->toEigen()).norm();
134 
135  const float handRobotDistance = leftWristKp.positionRobot->toEigen().head<2>().norm();
136 
137  const float priority = priorityFromDistance(distanceLeft, handRobotDistance);
138  const gaze_targets::TargetPriority targetPriority(
140 
141  gaze_targets::GazeTarget handTarget("left_hand",
142  leftWristKp.positionGlobal.value(),
143  targetPriority,
145  false);
146  gazeTargets.push_back(handTarget);
147  }
148 
149  // right wrist target
150  if (human.keypoints.count(rightWristKpName.value()) > 0)
151  {
152  const armem::human::PoseKeypoint rightWristKp =
153  human.keypoints.at(rightWristKpName.value());
154 
155  const float distanceRight =
156  (rightWristKp.positionGlobal->toEigen() - pelvisKp.positionGlobal->toEigen())
157  .norm();
158 
159  const float handRobotDistance = rightWristKp.positionRobot->toEigen().head<2>().norm();
160 
161  const float priority = priorityFromDistance(distanceRight, handRobotDistance);
162 
163  const gaze_targets::TargetPriority targetPriority(
165 
166  gaze_targets::GazeTarget handTarget("right_hand",
167  rightWristKp.positionGlobal.value(),
168  targetPriority,
170  false);
171  gazeTargets.push_back(handTarget);
172  }
173 
174  // combined wrist
175 
176  // some debugging
177  {
178  for (const auto& target : gazeTargets)
179  {
180  ARMARX_VERBOSE << target.name << ": " << target.priority;
181  }
182  }
183 
184  return gazeTargets;
185  }
186 
187  std::vector<gaze_targets::GazeTarget>
188  RobotGiver::updateTargetsAfterHandover(const armem::human::HumanPose& human) const
189  {
190 
191  const auto headKpName = util::headKeypoint(human.poseModelId);
192  const auto leftWristKpName = util::leftWristKeypoint(human.poseModelId);
193  const auto rightWristKpName = util::rightWristKeypoint(human.poseModelId);
194 
195  ARMARX_CHECK(headKpName.has_value());
196  ARMARX_CHECK(leftWristKpName.has_value());
197  ARMARX_CHECK(rightWristKpName.has_value());
198 
199  std::vector<gaze_targets::GazeTarget> gazeTargets;
200 
201  if (human.keypoints.count(headKpName.value()) == 0)
202  {
203  ARMARX_WARNING << deactivateSpam(1) << "Head keypoint `" << headKpName.value()
204  << "` not available!";
205  return {};
206  };
207 
208  // head target
209  {
210  const armem::human::PoseKeypoint headKp = human.keypoints.at(headKpName.value());
211 
212  const gaze_targets::TargetPriority targetPriority(
214 
215  gaze_targets::GazeTarget headTarget(
216  "head", headKp.positionGlobal.value(), targetPriority, Duration::Seconds(1), false);
217  gazeTargets.push_back(headTarget);
218  }
219 
220  return gazeTargets;
221  }
222 
223 
224 } // namespace armarx::view_selection::target_provider::handover
armarx::view_selection::target_provider::handover::util::rightWristKeypoint
std::optional< std::string > rightWristKeypoint(const std::string &poseModelId)
Definition: util.cpp:53
armarx::view_selection::target_provider::handover::Phase::PreHandover
@ PreHandover
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::targets
Brief description of class targets.
Definition: targets.h:38
armarx::view_selection::target_provider::handover::util::leftWristKeypoint
std::optional< std::string > leftWristKeypoint(const std::string &poseModelId)
Definition: util.cpp:33
armarx::view_selection::target_provider::handover
This file is part of ArmarX.
Definition: HandoverTargetProvider.cpp:3
armarx::view_selection::target_provider::handover::RobotGiver::updateTargets
std::vector< gaze_targets::GazeTarget > updateTargets(const armem::human::HumanPose &human) override
Definition: RobotGiver.cpp:37
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:668
Duration.h
armarx::view_selection::target_provider::handover::HandoverTargetProvider::robot_
const VirtualRobot::RobotPtr robot_
Definition: HandoverTargetProvider.h:49
armarx::view_selection::gaze_targets::GazeTarget
Business Object (BO) class of GazeTarget.
Definition: GazeTarget.h:39
util.h
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::view_selection::target_provider::handover::util::pelvisKeypoint
std::optional< std::string > pelvisKeypoint(const std::string &poseModelId)
Definition: util.cpp:73
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:136
armarx::view_selection::gaze_targets::AttentionType::TaskDriven
@ TaskDriven
Task-Driven attention has highest priority.
armarx::view_selection::target_provider::handover::util::headKeypoint
std::optional< std::string > headKeypoint(const std::string &poseModelId)
Definition: util.cpp:13
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
armarx::armem::human::HumanPose::poseModelId
std::string poseModelId
Definition: types.h:32
armarx::core::time::Duration::Seconds
static Duration Seconds(std::int64_t seconds)
Constructs a duration in seconds.
Definition: Duration.cpp:72
armarx::armem::human::PoseKeypoint
Definition: types.h:17
AttentionType.h
armarx::view_selection::target_provider::handover::RobotGiver::Params::minHandReachoutDistance
float minHandReachoutDistance
Definition: RobotGiver.h:48
armarx::armem::human::HumanPose
Definition: types.h:30
armarx::view_selection::target_provider::handover::RobotGiver::Params::maxHandoverInitializationDistance
float maxHandoverInitializationDistance
the distance below which the hand targets will be generated.
Definition: RobotGiver.h:46
ExpressionException.h
armarx::view_selection::target_provider::handover::RobotGiver::Params::headPriority
float headPriority
Definition: RobotGiver.h:53
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::armem::human::PoseKeypoint::positionGlobal
std::optional< armarx::FramedPosition > positionGlobal
Definition: types.h:26
armarx::armem::human::HumanPose::keypoints
KeyPointMap keypoints
Definition: types.h:35
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
GazeTarget.h
armarx::view_selection::target_provider::handover::RobotGiver::Params::maxHandReachoutDistance
float maxHandReachoutDistance
Definition: RobotGiver.h:49
armarx::view_selection::target_provider::handover::RobotGiver::Params::minHandoverDistance
float minHandoverDistance
Definition: RobotGiver.h:55
armarx::view_selection::gaze_targets::TargetPriority
The Priority of a GazeTarget.
Definition: TargetPriority.h:39
armarx::view_selection::target_provider::handover::RobotGiver::Params::handPriorityScaling
float handPriorityScaling
Definition: RobotGiver.h:51
RobotGiver.h
armarx::view_selection::target_provider::handover::Phase::PostHandover
@ PostHandover
norm
double norm(const Point &a)
Definition: point.hpp:102