Pointing.cpp
Go to the documentation of this file.
1#include "Pointing.h"
2
3#include <VirtualRobot/RobotNodeSet.h>
4
6
8
10
11#include "PointingIK.h"
12
14{
15 Pointing::Pointing(const Remote& remote) : remote_(remote)
16 {
17 setTag("Pointing");
18 }
19
20 void
22 {
23 aborted = false;
24
25 ARMARX_INFO << "Pointing with " << ((params.side == Side::LEFT) ? "left" : "right")
26 << " arm at " << params.target
27 << (params.handShape ? " with hand shape '" + *params.handShape + "'" : "");
28
29 remote_.trajectoryPlayer->stopTrajectoryPlayer();
30
31 VirtualRobot::RobotPtr robot = getRobot();
32
33 Eigen::Vector3f target = toGlobal(params.target, robot);
34 visualizeTarget(target);
35
36 armarx::TrajectoryPtr traj = computeArmTrajectory(robot, params.side, target);
37
38 addWristTrajectory(robot, params.side, traj);
39
40 if (params.handShape)
41 {
42 auto shapeJointValues = getShapeJointValues(robot, params.side, *params.handShape);
43 addHandTrajectory(robot, traj, shapeJointValues);
44 }
45
46 traj = traj->calculateTimeOptimalTrajectory(
47 params.maxVelocity, params.maxAcceleration, 0.0, IceUtil::Time::milliSeconds(10));
48
49 playTrajectory(traj);
50 }
51
52 void
54 {
55 aborted = true;
56 }
57
59 Pointing::getRobot()
60 {
62 robotReader.connect(remote_.memoryNameSystem);
63
64 auto robot = robotReader.getSynchronizedRobot(remote_.robotName);
65 if (not robot)
66 {
67 ARMARX_ERROR << "Could not get synchronized robot '" << remote_.robotName << "'";
69 }
70 return robot;
71 }
72
73 Eigen::Vector3f
74 Pointing::toGlobal(const FramedPosition& framedPosition, VirtualRobot::RobotPtr robot)
75 {
76 if (not(framedPosition.frame == armarx::GlobalFrame ||
77 robot->hasRobotNode(framedPosition.frame)))
78 {
79 ARMARX_ERROR << "'" << framedPosition.frame << "' is not a valid frame name";
81 }
82 return framedPosition.toGlobalEigen(robot);
83 }
84
85 void
86 Pointing::visualizeTarget(const Eigen::Vector3f& target)
87 {
88 auto layer = remote_.arviz.layer(constants::ARVIZ_LAYER_NAME);
89 layer.add(armarx::viz::Sphere("Pointing target")
90 .radius(50)
91 .color(armarx::viz::Color::orange())
92 .position(target));
93 remote_.arviz.commit(layer);
94 }
95
97 Pointing::computeArmTrajectory(VirtualRobot::RobotPtr robot, Side side, Eigen::Vector3f target)
98 {
99 ARMARX_VERBOSE << "Computing trajectory...";
100 auto ik = PointingIK(robot, side, target);
101
102 if (ik.isTargetReached()) // forearm already aligned with target
103 {
104 return armarx::TrajectoryPtr(new Trajectory);
105 }
106
107 do
108 {
109 if (ik.optimize() < 1e-6)
110 {
111 ARMARX_WARNING << "PointingIK didn't find a solution";
112 throw armarx::exceptions::local::PointingFailedException();
113 }
114 if (aborted)
115 {
116 ARMARX_INFO << "Pointing aborted";
117 throw armarx::exceptions::local::PointingAbortedException();
118 }
119 } while (not ik.isTargetReached());
120
121 ARMARX_VERBOSE << "Done computing trajectory";
122
123 return ik.getTrajectory();
124 }
125
126 void
127 Pointing::addWristTrajectory(VirtualRobot::RobotPtr robot, Side side, TrajectoryPtr traj)
128 {
129 auto humanMapping = robot->getHumanMapping();
130 ARMARX_CHECK(humanMapping) << "Robot '" << robot->getName() << "' has no human mapping";
131
132 auto armDescription = (side == LEFT) ? humanMapping->leftArm : humanMapping->rightArm;
133 auto wrist = armDescription.segments.wrist.nodeName;
134
135 auto nodeSetArm = robot->getRobotNodeSet(armDescription.nodeSet);
136
137 // iterate over all joints, starting from the wrist, to move them into a neutral position
138 std::for_each(nodeSetArm->begin() + nodeSetArm->getRobotNodeIndex(wrist),
139 nodeSetArm->end(),
140 [traj](VirtualRobot::RobotNodePtr robotNode) {
141 traj->addDimension({robotNode->getJointValue(), 0.0},
142 Ice::DoubleSeq(),
143 robotNode->getName());
144 });
145 }
146
147 std::map<std::string, float>
148 Pointing::getShapeJointValues(VirtualRobot::RobotPtr robot,
149 Side side,
150 const std::string& shapeName)
151 {
152 auto humanMapping = robot->getHumanMapping();
153 ARMARX_CHECK(humanMapping) << "Robot '" << robot->getName() << "' has no human mapping";
154 auto armDescription = (side == LEFT) ? humanMapping->leftArm : humanMapping->rightArm;
155 auto tcp = armDescription.segments.tcp.nodeName;
156
157 // get endeffector whichs tcp-name matches the tcp-name of the according hand
158 auto eefs = robot->getEndEffectors();
159 auto eef = std::find_if(eefs.begin(),
160 eefs.end(),
161 [&tcp](VirtualRobot::EndEffectorPtr eef)
162 { return eef->getTcpName() == tcp; });
163 ARMARX_CHECK(eef != eefs.end());
164
165 auto shape = (*eef)->getPreshape(shapeName);
166 if (not shape)
167 {
168 ARMARX_ERROR << "Hand '" << (*eef)->getName() << "' has no shape '" << shapeName << "'";
169 throw armarx::exceptions::local::PointingFailedException();
170 }
171 return shape->getRobotNodeJointValueMap();
172 }
173
174 void
175 Pointing::addHandTrajectory(VirtualRobot::RobotPtr robot,
177 const std::map<std::string, float>& shapeJointValues)
178 {
179 for (const auto& [jointName, targetValue] : shapeJointValues)
180 {
181 traj->addDimension({robot->getRobotNode(jointName)->getJointValue(), targetValue},
182 Ice::DoubleSeq(),
183 jointName);
184 }
185 }
186
187 void
188 Pointing::playTrajectory(armarx::TrajectoryPtr traj)
189 {
190 ARMARX_INFO << "Playing trajectory (" << traj->getTimeLength() << "s)";
191 remote_.trajectoryPlayer->loadJointTraj(traj);
192 remote_.trajectoryPlayer->startTrajectoryPlayer();
193
194
195 using namespace armarx::core::time;
196 DateTime waitUnil = DateTime::Now() + Duration::Seconds(traj->getTimeLength());
197
198 Clock clock;
199 while (DateTime::Now() < waitUnil)
200 {
201 if (aborted)
202 {
203 ARMARX_INFO << "Pointing aborted. Stopping trajectory";
204 remote_.trajectoryPlayer->stopTrajectoryPlayer();
205 throw armarx::exceptions::local::PointingAbortedException();
206 }
208 }
209 ARMARX_INFO << "Pointing target reached";
210 }
211
212} // namespace armarx::control::pointing::core
static DateTime Now()
Definition DateTime.cpp:51
static Duration Seconds(std::int64_t seconds)
Constructs a duration in seconds.
Definition Duration.cpp:72
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
The FramedPosition class.
Definition FramedPose.h:158
Eigen::Vector3f toGlobalEigen(const SharedRobotInterfacePrx &referenceRobot) const
void setTag(const LogTag &tag)
Definition Logging.cpp:54
virtual void connect(armem::client::MemoryNameSystem &memoryNameSystem)
VirtualRobot::RobotPtr getSynchronizedRobot(const std::string &name, const VirtualRobot::RobotIO::RobotDescription &loadMode=VirtualRobot::RobotIO::RobotDescription::eStructure, bool blocking=true)
void execute(const Parameters params)
Executes the pointing gesture.
Definition Pointing.cpp:21
void abort()
Aborts a running execution.
Definition Pointing.cpp:53
void waitFor(const Duration &duration) const
Wait for a certain duration.
Definition Clock.cpp:74
virtual Layer layer(std::string const &name) const
Definition Client.cpp:80
CommitResult commit(StagedCommit const &commit)
Definition Client.cpp:89
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Side
Describes the side of an arm.
Definition Side.h:11
#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
#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
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition Trajectory.h:52
std::chrono::system_clock Clock
Definition Stopwatch.h:10
Side side
Side of the arm to point with.
Definition Pointing.h:53
armarx::FramedPosition target
Position to point at.
Definition Pointing.h:56
std::optional< std::string > handShape
Name of the hand preshape to use.
Definition Pointing.h:59
armarx::armem::client::MemoryNameSystem & memoryNameSystem
Definition Pointing.h:46
void add(ElementT const &element)
Definition Layer.h:31