LookAtHumanHand.cpp
Go to the documentation of this file.
1 #include "LookAtHumanHand.h"
2 
3 #include <Eigen/Core>
4 #include <Eigen/Geometry>
5 
7 
9 {
10  LookAtHumanHand::LookAtHumanHand(const Services& srv) : Base(DefaultSkillDescription())
11  {
12  srv_.emplace(srv);
13  }
14 
16  LookAtHumanHand::init(const Base::SpecializedInitInput& in)
17  {
18  // initialize variables; store which human and which hand to follow
19 
20  fromAron(in.parameters.humanTrackingId, humanTrackingId);
21  // TODO, if implemented when using a different hand data type:
22  // fromAron(in.parameters.hand, hand);
24  {
26  }
27  else if (in.parameters.hand == armarx::view_selection::skills::arondto::Hand::RIGHT)
28  {
30  }
31  else
32  {
33  ARMARX_WARNING << "Could not parse which hand is requested to look at.";
34  }
35 
36  // TODO: or receive/pass the virtual robot differently?
37  handoverTargetProvider = std::make_unique<target_provider::handover::RobotReceiver>(
38  humanTrackingId, srv_->robot);
39  // TODO: always look at hands, despite just if the human is reaching out?
40  handoverTargetProvider->setPhase(target_provider::handover::Phase::PreHandover);
41 
42  return ::armarx::skills::Skill::InitResult{
43  .status = ::armarx::skills::TerminatedSkillStatus::Succeeded};
44  }
45 
47  LookAtHumanHand::main(const Base::SpecializedMainInput& in)
48  {
49  // repeatedly update the robot's gaze target to follow the requested human
50  // (method is blocking, as intended for skills)
51 
52  // setup metronome to control execution frequency
53  const auto metronomeTargetPeriod =
54  armarx::Duration::MilliSeconds(properties.updatePeriodMs);
55  armarx::Metronome metronome(metronomeTargetPeriod);
56 
57  while (!shouldSkillTerminate())
58  {
59  // update the view target based on the current pose of the human
60  update();
61  metronome.waitForNextTick();
62  }
63 
64  return ::armarx::skills::Skill::MainResult{
65  .status = ::armarx::skills::TerminatedSkillStatus::Succeeded};
66  }
67 
68  void
69  LookAtHumanHand::update()
70  {
71  std::optional<armem::human::HumanPose> latestPoseOfRequestedHuman =
72  getLatestPoseOfRequestedHuman();
73 
74  if (latestPoseOfRequestedHuman.has_value())
75  {
76  // updateTargetsAfterHandover generates targets to look at the head
77  // TODO: how to specify to look at a certain hand? (otherwise: remove parameter)
78  std::vector<gaze_targets::GazeTarget> gazeTargets =
79  handoverTargetProvider->updateTargetsAfterHandover(
80  latestPoseOfRequestedHuman.value());
81  for (const auto& gazeTarget : gazeTargets)
82  {
83  ARMARX_INFO << "Committing gaze target " << gazeTarget;
84  }
85  srv_->viewSelectionClient.commitGazeTargets(gazeTargets);
86  }
87  else
88  {
89  ARMARX_VERBOSE << "Did not find any pose for the requested human tracking ID";
90  }
91  }
92 
93  std::optional<armem::human::HumanPose>
94  LookAtHumanHand::getLatestPoseOfRequestedHuman()
95  {
96  // get the current pose of the human
98  builder.coreSegments()
99  .withName(srv_->humanPoseMemoryID.coreSegmentName)
101  .all()
102  .entities()
103  .all()
104  .snapshots()
105  .latest();
106  armem::client::QueryResult result =
107  srv_->memoryNameSystem.getReader(srv_->humanPoseMemoryID)
108  .query(builder.buildQueryInput());
109 
110  std::optional<armem::human::HumanPose> latestPoseOfRequestedHuman = std::nullopt;
111  if (result.success)
112  {
113  result.memory.forEachInstance(
114  [this, &latestPoseOfRequestedHuman](const armem::wm::EntityInstance& instance)
115  {
116  armem::human::HumanPose humanPose;
117  armarx::human::arondto::HumanPose dto =
118  armarx::human::arondto::HumanPose::FromAron(instance.data());
119  fromAron(dto, humanPose);
120  if (humanPose.humanTrackingId == humanTrackingId &&
121  (!latestPoseOfRequestedHuman.has_value() ||
122  humanPose.timestamp > latestPoseOfRequestedHuman->timestamp))
123  {
124  latestPoseOfRequestedHuman = humanPose;
125  }
126  });
127  }
128  else
129  {
130  ARMARX_WARNING << "Failed to query the human memory: " << result.errorMessage;
131  }
132  return latestPoseOfRequestedHuman;
133  }
134 
135  void
136  LookAtHumanHand::onStopRequested()
137  {
138  }
139 
140 
141 } // namespace armarx::view_selection::skills
armarx::view_selection::skills
This file is part of ArmarX.
Definition: constants.cpp:25
armarx::armem::client::query::EntitySelector::all
EntitySelector & all() override
Definition: selectors.cpp:104
armarx::control::pointing::core::RIGHT
@ RIGHT
Definition: Side.h:13
armarx::view_selection::target_provider::handover::Phase::PreHandover
@ PreHandover
armarx::skills::SimpleSpecializedSkill< arondto::LookAtHumanHandParams >::init
Skill::InitResult init() final
Definition: SimpleSpecializedSkill.h:62
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::armem::client::query::SnapshotSelector::latest
SnapshotSelector & latest()
Definition: selectors.cpp:30
armarx::armem::server::wm::EntityInstance
armem::wm::EntityInstance EntityInstance
Definition: forward_declarations.h:65
armarx::armem::client::query::ProviderSegmentSelector::entities
EntitySelector & entities()
Start specifying entities.
Definition: selectors.cpp:135
armarx::armem::client::query::Builder::buildQueryInput
QueryInput buildQueryInput() const
Definition: Builder.cpp:12
armarx::armem::client::query::EntitySelector::snapshots
SnapshotSelector & snapshots()
Start specifying entity snapshots.
Definition: selectors.cpp:92
armarx::armem::robot_state::RobotReader::Hand::Right
@ Right
armarx::armem::robot_state::RobotReader::Hand::Left
@ Left
armarx::armem::client::query::Builder::coreSegments
CoreSegmentSelector & coreSegments()
Start specifying core segments.
Definition: Builder.cpp:42
armarx::armem::client::query::CoreSegmentSelector::withName
CoreSegmentSelector & withName(const std::string &name) override
Definition: selectors.cpp:198
armarx::skills::SimpleSpecializedSkill
Definition: SimpleSpecializedSkill.h:10
armarx::view_selection::skills::LookAtHumanHand::LookAtHumanHand
LookAtHumanHand(const Services &srv)
Definition: LookAtHumanHand.cpp:10
armarx::skills::Skill::MainResult
A result struct for th main method of a skill.
Definition: Skill.h:39
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::skills::SimpleSpecializedSkill< arondto::LookAtHumanHandParams >::main
Skill::MainResult main() final
Definition: SimpleSpecializedSkill.h:71
aron_conversions.h
armarx::core::time::Metronome
Simple rate limiter for use in loops to maintain a certain frequency given a clock.
Definition: Metronome.h:34
armarx::skills::Skill::shouldSkillTerminate
bool shouldSkillTerminate() const
Returns whether the skill should terminate as soon as possible.
Definition: Skill.cpp:402
armarx::skills::Skill::InitResult
A result struct for skill initialization.
Definition: Skill.h:27
armarx::fromAron
void fromAron(const arondto::PackagePath &dto, PackageFileLocation &bo)
armarx::view_selection::skills::LookAtHumanHand::Services
Definition: LookAtHumanHand.h:47
armarx::armem::client::query::Builder
The query::Builder class provides a fluent-style specification of hierarchical queries.
Definition: Builder.h:21
armarx::armem::client::query::CoreSegmentSelector::providerSegments
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
Definition: selectors.cpp:178
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::armem::client::query::ProviderSegmentSelector::all
ProviderSegmentSelector & all() override
Definition: selectors.cpp:147
armarx::control::pointing::core::LEFT
@ LEFT
Definition: Side.h:12
LookAtHumanHand.h
armarx::core::time::Duration::MilliSeconds
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition: Duration.cpp:48