Pointing.cpp
Go to the documentation of this file.
1 #include "Pointing.h"
2 
3 #include <VirtualRobot/RobotNodeSet.h>
4 
5 #include <ArmarXCore/core/time.h>
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)
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";
113  }
114  if (aborted)
115  {
116  ARMARX_INFO << "Pointing aborted";
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 << "'";
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();
206  }
207  clock.waitFor(Duration::MilliSeconds(10));
208  }
209  ARMARX_INFO << "Pointing target reached";
210  }
211 
212 } // namespace armarx::control::pointing::core
armarx::control::pointing::core::Pointing::Pointing
Pointing(const Remote &remote)
Definition: Pointing.cpp:15
armarx::TrajectoryPtr
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition: Trajectory.h:52
armarx::control::pointing::core
Definition: Pointing.cpp:13
armarx::viz::Client::commit
CommitResult commit(StagedCommit const &commit)
Definition: Client.cpp:80
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::armem::robot_state::VirtualRobotReader
The VirtualRobotReader class.
Definition: VirtualRobotReader.h:40
armarx::control::pointing::core::Pointing::Parameters
Definition: Pointing.h:50
PointingIK.h
armarx::control::pointing::core::Pointing::Parameters::maxVelocity
double maxVelocity
Maximum velocity.
Definition: Pointing.h:62
armarx::control::pointing::core::Pointing::execute
void execute(const Parameters params)
Executes the pointing gesture.
Definition: Pointing.cpp:21
armarx::control::pointing::core::Pointing::Remote::memoryNameSystem
armarx::armem::client::MemoryNameSystem memoryNameSystem
Definition: Pointing.h:46
armarx::core::time::DateTime::Now
static DateTime Now()
Definition: DateTime.cpp:55
armarx::control::pointing::core::Pointing::Parameters::handShape
std::optional< std::string > handShape
Name of the hand preshape to use.
Definition: Pointing.h:59
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:688
constants.h
armarx::core::time
Definition: Clock.cpp:13
armarx::armem::robot_state::RobotReader::connect
virtual void connect(armem::client::MemoryNameSystem &memoryNameSystem)
Definition: RobotReader.cpp:48
armarx::viz::Layer::add
void add(ElementT const &element)
Definition: Layer.h:29
armarx::FramedPosition::toGlobalEigen
Eigen::Vector3f toGlobalEigen(const SharedRobotInterfacePrx &referenceRobot) const
Definition: FramedPose.cpp:752
armarx::core::time::Clock
Clock to get date/time from a specific clock type or wait for certain durations or until certain date...
Definition: Clock.h:26
armarx::viz::Sphere
Definition: Elements.h:134
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
IceInternal::Handle< Trajectory >
armarx::control::pointing::core::Side
Side
Describes the side of an arm.
Definition: Side.h:10
armarx::core::time::Duration::Seconds
static Duration Seconds(std::int64_t seconds)
Constructs a duration in seconds.
Definition: Duration.cpp:83
armarx::control::pointing::constants::ARVIZ_LAYER_NAME
const std::string ARVIZ_LAYER_NAME
Definition: constants.cpp:5
armarx::control::pointing::core::Pointing::Parameters::side
Side side
Side of the arm to point with.
Definition: Pointing.h:53
armarx::control::pointing::core::Pointing::abort
void abort()
Aborts a running execution.
Definition: Pointing.cpp:53
armarx::FramedPosition
The FramedPosition class.
Definition: FramedPose.h:142
VirtualRobotReader.h
armarx::control::pointing::core::Pointing::Parameters::maxAcceleration
double maxAcceleration
Maximum acceleration.
Definition: Pointing.h:65
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::armem::robot_state::VirtualRobotReader::getSynchronizedRobot
VirtualRobot::RobotPtr getSynchronizedRobot(const std::string &name, const VirtualRobot::RobotIO::RobotDescription &loadMode=VirtualRobot::RobotIO::RobotDescription::eStructure, bool blocking=true)
armarx::VariantType::Trajectory
const VariantTypeId Trajectory
Definition: Trajectory.h:44
armarx::control::pointing::core::Pointing::Parameters::target
armarx::FramedPosition target
Position to point at.
Definition: Pointing.h:56
armarx::core::time::Clock::waitFor
void waitFor(const Duration &duration) const
Wait for a certain duration.
Definition: Clock.cpp:75
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::exceptions::local::PointingFailedException
Definition: Pointing.h:19
armarx::control::pointing::core::Pointing::Remote::trajectoryPlayer
armarx::TrajectoryPlayerInterfacePrx trajectoryPlayer
Definition: Pointing.h:47
armarx::exceptions::local::PointingAbortedException
Definition: Pointing.h:23
armarx::viz::Color::orange
static Color orange(int o=255, int a=255)
2 Red + 1 Green
Definition: Color.h:119
Pointing.h
time.h
armarx::control::pointing::core::Pointing::Remote
Definition: Pointing.h:42
armarx::Logging::setTag
void setTag(const LogTag &tag)
Definition: Logging.cpp:55
armarx::control::pointing::core::Pointing::Remote::arviz
armarx::viz::Client arviz
Definition: Pointing.h:45
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::viz::Client::layer
Layer layer(std::string const &name) const
Definition: Client.cpp:73
armarx::control::pointing::core::Pointing::Remote::robotName
std::string robotName
Definition: Pointing.h:44
armarx::control::pointing::core::LEFT
@ LEFT
Definition: Side.h:12
armarx::core::time::Duration::MilliSeconds
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition: Duration.cpp:55
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18