CartesianPositionControlIK.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2014-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package RobotSkillTemplates::MotionControlGroup
19  * @author Peter Kaiser ( peter dot kaiser at kit dot edu )
20  * @date 2014
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
26 
27 #include <VirtualRobot/IK/ConstrainedOptimizationIK.h>
28 #include <VirtualRobot/IK/GenericIKSolver.h>
29 #include <VirtualRobot/IK/constraints/OrientationConstraint.h>
30 #include <VirtualRobot/IK/constraints/PositionConstraint.h>
31 #include <VirtualRobot/LinkedCoordinate.h>
32 #include <VirtualRobot/MathTools.h>
33 #include <VirtualRobot/RobotNodeSet.h> // IWYU pragma: keep
34 #include <VirtualRobot/XML/RobotIO.h>
35 
37 
41 
42 #include "../MotionControlGroupStatechartContext.h"
43 
44 using namespace armarx;
45 using namespace MotionControlGroup;
46 
47 // DO NOT EDIT NEXT LINE
48 CartesianPositionControlIK::SubClassRegistry
49  CartesianPositionControlIK::Registry(CartesianPositionControlIK::GetName(),
51 
54  CartesianPositionControlIKGeneratedBase<CartesianPositionControlIK>(stateData)
55 {
56 }
57 
58 void
60 {
61  // Create and install timeout condition
62  if (in.getTimeout() > 0)
63  {
64  setTimeoutEvent(in.getTimeout(), createEventTimeout());
65  }
66 }
67 
68 void
70 {
72  getContext<MotionControlGroupStatechartContext>();
73 
74  std::string kinChainName = in.getKinematicChainName();
75  float positionTolerance = in.getTcpPositionTolerance();
76  float orientationTolerance = in.getTcpOrientationTolerance();
77 
78 
79  VirtualRobot::RobotPtr robot = context->getLocalRobot() /*->clone("Armar3")*/;
81  context->getRobotStateComponent()->getSynchronizedRobot());
82 
83  // std::string robotfilepath = context->getRobotStateComponent()->getRobotFilename();
84  // if (!ArmarXDataPath::getAbsolutePath(robotfilepath, robotfilepath))
85  // {
86  // auto packages = context->getRobotStateComponent()->getArmarXPackages();
87  // for (auto & p : packages)
88  // {
89  // CMakePackageFinder finder(p);
90  // ArmarXDataPath::addDataPaths(finder.getDataDir());
91  // }
92  // if (!ArmarXDataPath::getAbsolutePath(robotfilepath, robotfilepath))
93  // {
94  // ARMARX_WARNING << "Could not get absolute robot model filepath for relative path : " << robotfilepath << " - using network clone";
95  // robotfilepath = "";
96  // }
97  // }
98  VirtualRobot::RobotPtr localrobot = robot; //VirtualRobot::RobotIO::loadRobot(robotfilepath);
99  // RemoteRobot::synchronizeLocalClone(localrobot, context->getRobotStateComponent()->getSynchronizedRobot());
100 
101  if (!robot)
102  {
103  ARMARX_WARNING << "Could not create robot" << flush;
104  emitFailure();
105  }
106 
107  if (!robot->hasRobotNodeSet(kinChainName))
108  {
109  ARMARX_WARNING << "Kinematic Chain '" << kinChainName << "' not available" << flush;
110  emitFailure();
111  }
112 
113  auto nodeSet = localrobot->getRobotNodeSet(kinChainName);
114 
116  VirtualRobot::IKSolver::CartesianSelection ikType = VirtualRobot::IKSolver::All;
117  if (isInputParameterSet("TcpTargetPosition") && isInputParameterSet("TcpTargetOrientation"))
118  {
119  ikType = VirtualRobot::IKSolver::All;
120 
121  FramedPositionPtr targetPosition = in.getTcpTargetPosition();
122  FramedOrientationPtr targetOrientation = in.getTcpTargetOrientation();
123  ARMARX_INFO << "Target position (Frame = " << targetPosition->getFrame()
124  << "): " << targetPosition->toEigen();
125  ARMARX_INFO << "Target orientation (Frame = " << targetOrientation->getFrame()
126  << "): " << targetOrientation->toEigen();
127  Eigen::Vector3f rpy;
129  mat.block<3, 3>(0, 0) = targetOrientation->toEigen();
130  VirtualRobot::MathTools::eigen4f2rpy(mat, rpy);
131  ARMARX_INFO << "rpy in same frame: " << rpy;
132 
133  targetPosition->changeToGlobal(robot);
134  targetOrientation->changeToGlobal(robot);
135 
136  target = new FramedPose(
137  targetOrientation->toEigen(), targetPosition->toEigen(), armarx::GlobalFrame, "");
138  }
139  else if (isInputParameterSet("TcpTargetPosition"))
140  {
142 
143  FramedPositionPtr targetPosition = in.getTcpTargetPosition();
144 
145  targetPosition->changeToGlobal(robot);
146 
147  ARMARX_INFO << "Target position (Frame = " << targetPosition->getFrame() << ": "
148  << targetPosition->toEigen();
149 
150  target = new FramedPose(
151  Eigen::Matrix3f::Identity(), targetPosition->toEigen(), armarx::GlobalFrame, "");
152  }
153  else if (isInputParameterSet("TcpTargetOrientation"))
154  {
156 
157  FramedOrientationPtr targetOrientation = in.getTcpTargetOrientation();
158 
159  targetOrientation->changeToGlobal(robot);
160 
161  ARMARX_INFO << "Target orientation (Frame = " << targetOrientation->getFrame() << ": "
162  << targetOrientation->toEigen();
163 
164  target = new FramedPose(
165  targetOrientation->toEigen(), Eigen::Vector3f(0, 0, 0), armarx::GlobalFrame, "");
166  }
168  ARMARX_VERBOSE << VAROUT(robot->getGlobalPose());
169  context->getDebugDrawerTopicProxy()->setPoseDebugLayerVisu("RobotPose",
170  new Pose(robot->getGlobalPose()));
171  // Eigen::Matrix4f globalTargetPose = target->toRootEigen(robot);
172  // robot->setGlobalPose(Eigen::Matrix4f::Identity());
173 
174  Eigen::Matrix4f globalTargetPose = target->toEigen();
175  VirtualRobot::ConstraintPtr positionConstraint(
176  new VirtualRobot::PositionConstraint(localrobot,
177  nodeSet,
178  nodeSet->getTCP(),
179  globalTargetPose.block<3, 1>(0, 3),
180  ikType,
181  positionTolerance));
182  positionConstraint->setOptimizationFunctionFactor(1);
183 
184  VirtualRobot::ConstraintPtr orientationConstraint(
185  new VirtualRobot::OrientationConstraint(localrobot,
186  nodeSet,
187  nodeSet->getTCP(),
188  globalTargetPose.block<3, 3>(0, 0),
189  ikType,
190  orientationTolerance));
191  orientationConstraint->setOptimizationFunctionFactor(1000);
192 
193  // VirtualRobot::GenericIKSolver ikSolver(robot->getRobotNodeSet(kinChainName), VirtualRobot::JacobiProvider::eSVDDamped);
194  // ikSolver.setMaximumError(positionTolerance, orientationTolerance);
195  // ikSolver.setupJacobian(jacobianStepSize, jacobianMaxLoops);
196  // ikSolver.solve(globalTargetPose, ikType, ikMaxLoops);
197  // Instantiate solver and generate IK solution
198  IceUtil::Time start = IceUtil::Time::now();
199  VirtualRobot::ConstrainedOptimizationIK ikSolver(localrobot, nodeSet);
200  ARMARX_INFO << "IK " << VAROUT(positionTolerance) << VAROUT(orientationTolerance);
201  ikSolver.addConstraint(positionConstraint);
202  ikSolver.addConstraint(orientationConstraint);
203  ikSolver.initialize();
204 
205  bool ikSuccess = ikSolver.solve();
206  ARMARX_INFO << "Solving IK took: " << (IceUtil::Time::now() - start).toMilliSecondsDouble()
207  << " ms " << VAROUT(ikSuccess);
208 
209  float remainingErrorPos =
210  (globalTargetPose.block<3, 1>(0, 3) - nodeSet->getTCP()->getGlobalPose().block<3, 1>(0, 3))
211  .norm();
212  Eigen::Matrix4f deltaMat = globalTargetPose * nodeSet->getTCP()->getGlobalPose().inverse();
213  Eigen::AngleAxisf aa(deltaMat.block<3, 3>(0, 0));
214  float remaingErrorOri = fabs(aa.angle());
215  // ikSuccess = (remainingErrorPos < positionTolerance && remaingErrorOri < orientationTolerance && ikType == VirtualRobot::IKSolver::All)
216  // || (ikType == VirtualRobot::IKSolver::Position && remainingErrorPos < positionTolerance)
217  // || (ikType == VirtualRobot::IKSolver::Orientation && remaingErrorOri < orientationTolerance);
218  ARMARX_DEBUG << VAROUT(globalTargetPose) << "Delta: " << deltaMat;
219  if (ikSuccess)
220  {
221  ARMARX_INFO << "Found IK solution: remaining position error " << remainingErrorPos
222  << " mm, orientation error: " << remaingErrorOri << " rad ("
223  << (remaingErrorOri * 180 / M_PI) << " deg)";
224  }
225  else
226  {
227  ARMARX_WARNING << "IK Solver failed: remaining position error " << remainingErrorPos
228  << " mm, orientation error: " << remaingErrorOri << " rad ("
229  << (remaingErrorOri * 180 / M_PI) << " deg)";
230  ARMARX_DEBUG << "Reached Pose: " << nodeSet->getTCP()->getGlobalPose();
231  context->getDebugDrawerTopicProxy()->setPoseDebugLayerVisu(
232  "UnreachedIKPose", new Pose(target->toGlobalEigen(robot)));
233  robot->setGlobalPose(robot->getGlobalPose());
234  context->getDebugDrawerTopicProxy()->setPoseDebugLayerVisu(
235  "BestFoundIKPose", new Pose(nodeSet->getTCP()->getGlobalPose()));
236  if (in.getAlwaysExecuteBestFoundIkSolution())
237  {
239  << "Using failed IK anyway due to AlwaysExecuteBestFoundIkSolution == true";
240  }
241  }
242 
243  if (!ikSuccess && !in.getAlwaysExecuteBestFoundIkSolution())
244  {
245  emitFailure();
246  }
247  else
248  {
249  // Convert solution to state output format
250  std::map<std::string, float> jointTargetValues;
251  std::map<std::string, float> jointVelocities;
252 
253  VirtualRobot::RobotNodeSetPtr kinematicChain = localrobot->getRobotNodeSet(kinChainName);
254 
255  for (unsigned int i = 0; i < kinematicChain->getSize(); i++)
256  {
257  VirtualRobot::RobotNodePtr node = kinematicChain->getNode(i);
258 
259  jointTargetValues[node->getName()] = node->getJointValue();
260  jointVelocities[node->getName()] = 1.0f;
261  }
262 
263  out.setJointTargetValues(jointTargetValues);
264  out.setJointVelocities(jointVelocities);
265  out.setJointTargetTolerance(0.1f);
266 
267  emitSuccess();
268  }
269 }
270 
271 void
273 {
274 }
275 
276 void
278 {
279 }
280 
281 // DO NOT EDIT NEXT FUNCTION
284 {
285  return XMLStateFactoryBasePtr(new CartesianPositionControlIK(stateData));
286 }
RemoteRobot.h
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getLocalRobot
const VirtualRobot::RobotPtr getLocalRobot()
Definition: MotionControlGroupStatechartContext.h:96
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::MotionControlGroup::CartesianPositionControlIK::onBreak
void onBreak() override
Definition: CartesianPositionControlIK.cpp:272
GfxTL::Orientation
ScalarT Orientation(const VectorXD< 2, ScalarT > &p1, const VectorXD< 2, ScalarT > &p2, const VectorXD< 2, ScalarT > &c)
Definition: Orientation.h:10
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::MotionControlGroup::MotionControlGroupStatechartContext
Definition: MotionControlGroupStatechartContext.h:75
armarx::RemoteRobot::synchronizeLocalClone
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
Definition: RemoteRobot.cpp:522
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:36
armarx::MotionControlGroup::CartesianPositionControlIK::run
void run() override
Definition: CartesianPositionControlIK.cpp:69
armarx::MotionControlGroup::CartesianPositionControlIK
Definition: CartesianPositionControlIK.h:31
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
Pose.h
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:65
armarx::XMLStateConstructorParams
Definition: XMLState.h:49
armarx::MotionControlGroup::CartesianPositionControlIK::CartesianPositionControlIK
CartesianPositionControlIK(XMLStateConstructorParams stateData)
Definition: CartesianPositionControlIK.cpp:52
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:668
armarx::MotionControlGroup::CartesianPositionControlIK::onExit
void onExit() override
Definition: CartesianPositionControlIK.cpp:277
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getDebugDrawerTopicProxy
DebugDrawerInterfacePrx getDebugDrawerTopicProxy()
Definition: MotionControlGroupStatechartContext.h:144
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:64
IceInternal::Handle< FramedPose >
armarx::MotionControlGroup::CartesianPositionControlIK::Registry
static SubClassRegistry Registry
Definition: CartesianPositionControlIK.h:45
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
armarx::XMLStateTemplate
Class for legacy to stay compatible with old statecharts.
Definition: XMLState.h:146
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getRobotStateComponent
RobotStateComponentInterfacePrx getRobotStateComponent()
Definition: MotionControlGroupStatechartContext.h:114
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::NJointTaskSpaceDMPControllerMode::CartesianSelection
CartesianSelection
Definition: ControllerInterface.ice:34
armarx::MotionControlGroup::CartesianPositionControlIK::CreateInstance
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Definition: CartesianPositionControlIK.cpp:283
armarx::channels::KinematicUnitObserver::jointVelocities
const KinematicUnitDatafieldCreator jointVelocities("jointVelocities")
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
CartesianPositionControlIK.h
CMakePackageFinder.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::MotionControlGroup::CartesianPositionControlIK::onEnter
void onEnter() override
Definition: CartesianPositionControlIK.cpp:59
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19
RobotStatechartContext.h
armarx::control::njoint_mp_controller::task_space::ConstraintPtr
std::shared_ptr< Constraint1 > ConstraintPtr
Definition: KVILImpedanceController.h:56