GuideHumanToRoom.cpp
Go to the documentation of this file.
1#include "GuideHumanToRoom.h"
2
3#include <math.h>
4
5#include <cmath>
6#include <string>
7
8#include <Eigen/Core>
9#include <Eigen/Geometry>
10
11#include <VirtualRobot/VirtualRobot.h>
12
17
20
32
34{
36 const NavigatingSkillHelper::Services& helperSrv,
37 const Services& srv) :
38 Base(DefaultSkillDescription()), helper(helperProperties, helperSrv)
39 {
40 srv_.emplace(srv);
41 }
42
44 GuideHumanToRoom::init(const Base::SpecializedInitInput& in)
45 {
46 ARMARX_CHECK(srv_.has_value());
47
48 helper.init(in.parameters.navigatingSkillParams,
49 DefaultSkillDescription().skillId.skillName);
50
51 return ::armarx::skills::Skill::InitResult{
53 }
54
56 GuideHumanToRoom::main(const Base::SpecializedMainInput& in)
57 {
58 const core::Pose globalTarget = getTargetInFrontOfRoom(in.parameters.room);
59
60 ARMARX_INFO << "moving to target " << VAROUT(globalTarget.matrix());
61
62 // execute
63 ARMARX_INFO << "Sending navigation request";
64 helper.getNavigator()->moveTo(globalTarget, core::NavigationFrame::Absolute);
65
66 // Wait until goal is reached
67 ARMARX_INFO << "Waiting until goal is reached.";
68 client::StopEvent se = helper.getNavigator()->waitForStop();
69 if (se)
70 {
71 ARMARX_INFO << "Goal " << QUOTED(globalTarget.translation()) << "reached.";
72 }
73 else
74 {
75 if (se.isSafetyStopTriggeredEvent())
76 {
77 ARMARX_ERROR << "Safety stop was triggered!";
78
79 return ::armarx::skills::Skill::MainResult{
81 }
82 if (se.isUserAbortTriggeredEvent())
83 {
84 ARMARX_ERROR << "Aborted by user!";
85
86 return ::armarx::skills::Skill::MainResult{
88 }
89 if (se.isInternalErrorEvent())
90 {
91 ARMARX_ERROR << "Unknown internal error occured! "
92 << se.toInternalErrorEvent().message;
93
94 return ::armarx::skills::Skill::MainResult{
96 }
97 if (se.isGlobalPlanningFailedEvent())
98 {
99 ARMARX_ERROR << "Global planning failed! "
100 << se.toGlobalPlanningFailedEvent().message;
101
102 return ::armarx::skills::Skill::MainResult{
104 }
105
106 ARMARX_ERROR << "Unknown event!";
107 return ::armarx::skills::Skill::MainResult{
109 }
110
111
112 return ::armarx::skills::Skill::MainResult{
114 }
115
116 void
117 GuideHumanToRoom::onStopRequested()
118 {
119 if (helper.getNavigator().has_value())
120 {
121 ARMARX_CHECK(helper.getNavigator().has_value());
122 helper.getNavigator()->stop();
123 }
124 }
125
127 GuideHumanToRoom::getTargetInFrontOfRoom(const std::string& roomName) const
128 {
129 const algorithms::Costmap costmap = [&]
130 {
131 const memory::client::costmap::Reader::Query costmapQuery{
132 .providerName = properties.distanceToObstacleCostmapProvider,
133 .name = "distance_to_obstacles",
134 .timestamp = Clock::Now()};
135
136 const auto result = srv_->costmapReader.query(costmapQuery);
137 ARMARX_CHECK(result) << result.errorMessage;
138 ARMARX_CHECK(result.costmap.has_value());
139 return result.costmap.value();
140 }();
141
142 const armarx::navigation::algorithms::Room room = [&]
143 {
144 const memory::client::rooms::Reader::Query roomQuery{.providerName =
145 properties.roomsProvider,
146 .name = roomName,
147 .timestamp = Clock::Now()};
148
149 const auto result = srv_->roomsReader.query(roomQuery);
150 ARMARX_CHECK(result) << "Failed to query room " << QUOTED(roomName) << " from provider `"
151 << properties.roomsProvider
152 << "`. Reason: " << result.errorMessage;
153 ARMARX_CHECK_NOT_EMPTY(result.rooms);
154 ARMARX_CHECK_EQUAL(result.rooms.size(), 1);
155
156 return result.rooms.front();
157 }();
158
159 const VirtualRobot::RobotPtr robot =
160 srv_->virtualRobotReader.getRobotWaiting(properties.robotName);
162 ARMARX_CHECK(srv_->virtualRobotReader.synchronizeRobotPose(*robot, Clock::Now()));
163
164 const core::Pose global_T_robot(robot->getGlobalPose());
165
166 rooms::RoomNavigationTargetCreator::Params algoParams;
167 rooms::RoomNavigationTargetCreator algo(algoParams);
168 auto result = algo.getClosestPositionOutsideOfRoom(
169 costmap, room, global_T_robot.translation(), &srv_->arviz);
170
171 const core::Direction dirToRoom = result.global_P_roomEntry - result.global_P_robot;
172
173 // the robot should point to the room entry
174 const float yaw = std::atan2(dirToRoom.y(), dirToRoom.x()) - M_PI_2f32;
175
176 // TODO maybe rotate robot a bit towards the human?
177
178 core::Pose global_T_robot_target = core::Pose::Identity();
179 global_T_robot_target.translation() = result.global_P_robot;
180 global_T_robot_target.linear() =
181 Eigen::AngleAxisf(yaw, Eigen::Vector3f::UnitZ()).toRotationMatrix();
182
183 return global_T_robot_target;
184 }
185
186
187} // namespace armarx::navigation::skills
#define ARMARX_CHECK_NOT_EMPTY(c)
#define VAROUT(x)
#define QUOTED(x)
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
::armarx::skills::SimpleSpecializedSkill< Params > Base
GuideHumanToRoom(const NavigatingSkillHelper::Properties &helperProperties, const NavigatingSkillHelper::Services &helperSrv, const Services &srv)
static armarx::skills::SkillDescription DefaultSkillDescription()
std::optional< client::Navigator > & getNavigator()
void init(const arondto::NavigatingSkillParams &params, const std::string &id)
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
Eigen::Vector3f Direction
Definition basic_types.h:39
Eigen::Isometry3f Pose
Definition basic_types.h:31
A result struct for skill initialization.
Definition Skill.h:50
A result struct for th main method of a skill.
Definition Skill.h:62