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{
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);
23 if (in.parameters.hand == armarx::view_selection::skills::arondto::Hand::LEFT)
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{
44 }
45
46 ::armarx::skills::Skill::MainResult
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{
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
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
CoreSegmentSelector & coreSegments()
Start specifying core segments.
Definition Builder.cpp:42
CoreSegmentSelector & withName(const std::string &name) override
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
SnapshotSelector & snapshots()
Start specifying entity snapshots.
Definition selectors.cpp:92
EntitySelector & entities()
Start specifying entities.
ProviderSegmentSelector & all() override
bool shouldSkillTerminate() const override
Returns whether the skill should terminate as soon as possible.
Definition Skill.cpp:469
::armarx::skills::SimpleSpecializedSkill< Params > Base
static armarx::skills::SkillDescription DefaultSkillDescription()
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file is part of ArmarX.
Definition constants.cpp:26
void fromAron(const arondto::PackagePath &dto, PackageFileLocation &bo)
wm::Memory memory
The slice of the memory that matched the query.
Definition Query.h:58
std::optional< std::string > humanTrackingId
Definition types.h:47
A result struct for skill initialization.
Definition Skill.h:50