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 #include "../MotionControlGroupStatechartContext.h"
27 
31 
33 #include <VirtualRobot/IK/ConstrainedOptimizationIK.h>
34 #include <VirtualRobot/IK/GenericIKSolver.h>
35 #include <VirtualRobot/IK/constraints/PositionConstraint.h>
36 #include <VirtualRobot/IK/constraints/OrientationConstraint.h>
37 #include <VirtualRobot/LinkedCoordinate.h>
38 #include <VirtualRobot/XML/RobotIO.h>
39 
40 using namespace armarx;
41 using namespace MotionControlGroup;
42 
43 // DO NOT EDIT NEXT LINE
44 CartesianPositionControlIK::SubClassRegistry CartesianPositionControlIK::Registry(CartesianPositionControlIK::GetName(), &CartesianPositionControlIK::CreateInstance);
45 
46 
47 
50  CartesianPositionControlIKGeneratedBase<CartesianPositionControlIK>(stateData)
51 {
52 }
53 
55 {
56  // Create and install timeout condition
57  if (in.getTimeout() > 0)
58  {
59  setTimeoutEvent(in.getTimeout(), createEventTimeout());
60  }
61 }
62 
64 {
65  MotionControlGroupStatechartContext* context = getContext<MotionControlGroupStatechartContext>();
66 
67  std::string kinChainName = in.getKinematicChainName();
68  float positionTolerance = in.getTcpPositionTolerance();
69  float orientationTolerance = in.getTcpOrientationTolerance();
70 
71 
72 
73  VirtualRobot::RobotPtr robot = context->getLocalRobot()/*->clone("Armar3")*/;
74  RemoteRobot::synchronizeLocalClone(robot, context->getRobotStateComponent()->getSynchronizedRobot());
75 
76  // std::string robotfilepath = context->getRobotStateComponent()->getRobotFilename();
77  // if (!ArmarXDataPath::getAbsolutePath(robotfilepath, robotfilepath))
78  // {
79  // auto packages = context->getRobotStateComponent()->getArmarXPackages();
80  // for (auto & p : packages)
81  // {
82  // CMakePackageFinder finder(p);
83  // ArmarXDataPath::addDataPaths(finder.getDataDir());
84  // }
85  // if (!ArmarXDataPath::getAbsolutePath(robotfilepath, robotfilepath))
86  // {
87  // ARMARX_WARNING << "Could not get absolute robot model filepath for relative path : " << robotfilepath << " - using network clone";
88  // robotfilepath = "";
89  // }
90  // }
91  VirtualRobot::RobotPtr localrobot = robot;//VirtualRobot::RobotIO::loadRobot(robotfilepath);
92  // RemoteRobot::synchronizeLocalClone(localrobot, context->getRobotStateComponent()->getSynchronizedRobot());
93 
94  if (!robot)
95  {
96  ARMARX_WARNING << "Could not create robot" << flush;
97  emitFailure();
98  }
99 
100  if (!robot->hasRobotNodeSet(kinChainName))
101  {
102  ARMARX_WARNING << "Kinematic Chain '" << kinChainName << "' not available" << flush;
103  emitFailure();
104  }
105 
106  auto nodeSet = localrobot->getRobotNodeSet(kinChainName);
107 
109  VirtualRobot::IKSolver::CartesianSelection ikType = VirtualRobot::IKSolver::All;
110  if (isInputParameterSet("TcpTargetPosition") && isInputParameterSet("TcpTargetOrientation"))
111  {
112  ikType = VirtualRobot::IKSolver::All;
113 
114  FramedPositionPtr targetPosition = in.getTcpTargetPosition();
115  FramedOrientationPtr targetOrientation = in.getTcpTargetOrientation();
116  ARMARX_INFO << "Target position (Frame = " << targetPosition->getFrame() << "): " << targetPosition->toEigen();
117  ARMARX_INFO << "Target orientation (Frame = " << targetOrientation->getFrame() << "): " << targetOrientation->toEigen();
118  Eigen::Vector3f rpy;
120  mat.block<3, 3>(0, 0) = targetOrientation->toEigen();
121  VirtualRobot::MathTools::eigen4f2rpy(mat, rpy);
122  ARMARX_INFO << "rpy in same frame: " << rpy;
123 
124  targetPosition->changeToGlobal(robot);
125  targetOrientation->changeToGlobal(robot);
126 
127  target = new FramedPose(targetOrientation->toEigen(), targetPosition->toEigen(), armarx::GlobalFrame, "");
128  }
129  else if (isInputParameterSet("TcpTargetPosition"))
130  {
132 
133  FramedPositionPtr targetPosition = in.getTcpTargetPosition();
134 
135  targetPosition->changeToGlobal(robot);
136 
137  ARMARX_INFO << "Target position (Frame = " << targetPosition->getFrame() << ": " << targetPosition->toEigen();
138 
139  target = new FramedPose(Eigen::Matrix3f::Identity(), targetPosition->toEigen(), armarx::GlobalFrame, "");
140  }
141  else if (isInputParameterSet("TcpTargetOrientation"))
142  {
144 
145  FramedOrientationPtr targetOrientation = in.getTcpTargetOrientation();
146 
147  targetOrientation->changeToGlobal(robot);
148 
149  ARMARX_INFO << "Target orientation (Frame = " << targetOrientation->getFrame() << ": " << targetOrientation->toEigen();
150 
151  target = new FramedPose(targetOrientation->toEigen(), Eigen::Vector3f(0, 0, 0), armarx::GlobalFrame, "");
152  }
154  ARMARX_VERBOSE << VAROUT(robot->getGlobalPose());
155  context->getDebugDrawerTopicProxy()->setPoseDebugLayerVisu("RobotPose", new Pose(robot->getGlobalPose()));
156  // Eigen::Matrix4f globalTargetPose = target->toRootEigen(robot);
157  // robot->setGlobalPose(Eigen::Matrix4f::Identity());
158 
159  Eigen::Matrix4f globalTargetPose = target->toEigen();
160  VirtualRobot::ConstraintPtr positionConstraint(new VirtualRobot::PositionConstraint(localrobot, nodeSet, nodeSet->getTCP(),
161  globalTargetPose.block<3, 1>(0, 3), ikType, positionTolerance));
162  positionConstraint->setOptimizationFunctionFactor(1);
163 
164  VirtualRobot::ConstraintPtr orientationConstraint(new VirtualRobot::OrientationConstraint(localrobot, nodeSet, nodeSet->getTCP(),
165  globalTargetPose.block<3, 3>(0, 0), ikType, orientationTolerance));
166  orientationConstraint->setOptimizationFunctionFactor(1000);
167 
168  // VirtualRobot::GenericIKSolver ikSolver(robot->getRobotNodeSet(kinChainName), VirtualRobot::JacobiProvider::eSVDDamped);
169  // ikSolver.setMaximumError(positionTolerance, orientationTolerance);
170  // ikSolver.setupJacobian(jacobianStepSize, jacobianMaxLoops);
171  // ikSolver.solve(globalTargetPose, ikType, ikMaxLoops);
172  // Instantiate solver and generate IK solution
173  IceUtil::Time start = IceUtil::Time::now();
174  VirtualRobot::ConstrainedOptimizationIK ikSolver(localrobot, nodeSet);
175  ARMARX_INFO << "IK " << VAROUT(positionTolerance) << VAROUT(orientationTolerance);
176  ikSolver.addConstraint(positionConstraint);
177  ikSolver.addConstraint(orientationConstraint);
178  ikSolver.initialize();
179 
180  bool ikSuccess = ikSolver.solve();
181  ARMARX_INFO << "Solving IK took: " << (IceUtil::Time::now() - start).toMilliSecondsDouble() << " ms " << VAROUT(ikSuccess);
182 
183  float remainingErrorPos = (globalTargetPose.block<3, 1>(0, 3) - nodeSet->getTCP()->getGlobalPose().block<3, 1>(0, 3)).norm();
184  Eigen::Matrix4f deltaMat = globalTargetPose * nodeSet->getTCP()->getGlobalPose().inverse();
185  Eigen::AngleAxisf aa(deltaMat.block<3, 3>(0, 0));
186  float remaingErrorOri = fabs(aa.angle());
187  // ikSuccess = (remainingErrorPos < positionTolerance && remaingErrorOri < orientationTolerance && ikType == VirtualRobot::IKSolver::All)
188  // || (ikType == VirtualRobot::IKSolver::Position && remainingErrorPos < positionTolerance)
189  // || (ikType == VirtualRobot::IKSolver::Orientation && remaingErrorOri < orientationTolerance);
190  ARMARX_DEBUG << VAROUT(globalTargetPose) << "Delta: " << deltaMat;
191  if (ikSuccess)
192  {
193  ARMARX_INFO << "Found IK solution: remaining position error " << remainingErrorPos << " mm, orientation error: " << remaingErrorOri << " rad (" << (remaingErrorOri * 180 / M_PI) << " deg)";
194  }
195  else
196  {
197  ARMARX_WARNING << "IK Solver failed: remaining position error " << remainingErrorPos << " mm, orientation error: " << remaingErrorOri << " rad (" << (remaingErrorOri * 180 / M_PI) << " deg)";
198  ARMARX_DEBUG << "Reached Pose: " << nodeSet->getTCP()->getGlobalPose();
199  context->getDebugDrawerTopicProxy()->setPoseDebugLayerVisu("UnreachedIKPose", new Pose(target->toGlobalEigen(robot)));
200  robot->setGlobalPose(robot->getGlobalPose());
201  context->getDebugDrawerTopicProxy()->setPoseDebugLayerVisu("BestFoundIKPose", new Pose(nodeSet->getTCP()->getGlobalPose()));
202  if (in.getAlwaysExecuteBestFoundIkSolution())
203  {
204  ARMARX_WARNING << "Using failed IK anyway due to AlwaysExecuteBestFoundIkSolution == true";
205  }
206  }
207 
208  if (!ikSuccess && !in.getAlwaysExecuteBestFoundIkSolution())
209  {
210  emitFailure();
211  }
212  else
213  {
214  // Convert solution to state output format
215  std::map<std::string, float> jointTargetValues;
216  std::map<std::string, float> jointVelocities;
217 
218  VirtualRobot::RobotNodeSetPtr kinematicChain = localrobot->getRobotNodeSet(kinChainName);
219 
220  for (unsigned int i = 0; i < kinematicChain->getSize(); i++)
221  {
222  VirtualRobot::RobotNodePtr node = kinematicChain->getNode(i);
223 
224  jointTargetValues[node->getName()] = node->getJointValue();
225  jointVelocities[node->getName()] = 1.0f;
226  }
227 
228  out.setJointTargetValues(jointTargetValues);
229  out.setJointVelocities(jointVelocities);
230  out.setJointTargetTolerance(0.1f);
231 
232  emitSuccess();
233  }
234 }
235 
237 {
238 }
239 
241 {
242 }
243 
244 // DO NOT EDIT NEXT FUNCTION
246 {
247  return XMLStateFactoryBasePtr(new CartesianPositionControlIK(stateData));
248 }
249 
RemoteRobot.h
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getLocalRobot
const VirtualRobot::RobotPtr getLocalRobot()
Definition: MotionControlGroupStatechartContext.h:83
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::control::njoint_mp_controller::task_space::ConstraintPtr
std::shared_ptr< Constraint > ConstraintPtr
Definition: KVILImpedanceController.h:60
armarx::MotionControlGroup::CartesianPositionControlIK::onBreak
void onBreak() override
Definition: CartesianPositionControlIK.cpp:236
GfxTL::Orientation
ScalarT Orientation(const VectorXD< 2, ScalarT > &p1, const VectorXD< 2, ScalarT > &p2, const VectorXD< 2, ScalarT > &c)
Definition: Orientation.h:9
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::MotionControlGroup::MotionControlGroupStatechartContext
Definition: MotionControlGroupStatechartContext.h:66
armarx::RemoteRobot::synchronizeLocalClone
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
Definition: RemoteRobot.cpp:448
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:37
armarx::MotionControlGroup::CartesianPositionControlIK::run
void run() override
Definition: CartesianPositionControlIK.cpp:63
armarx::MotionControlGroup::CartesianPositionControlIK
Definition: CartesianPositionControlIK.h:31
Pose.h
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
armarx::XMLStateConstructorParams
Definition: XMLState.h:50
armarx::MotionControlGroup::CartesianPositionControlIK::CartesianPositionControlIK
CartesianPositionControlIK(XMLStateConstructorParams stateData)
Definition: CartesianPositionControlIK.cpp:48
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:688
armarx::MotionControlGroup::CartesianPositionControlIK::onExit
void onExit() override
Definition: CartesianPositionControlIK.cpp:240
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getDebugDrawerTopicProxy
DebugDrawerInterfacePrx getDebugDrawerTopicProxy()
Definition: MotionControlGroupStatechartContext.h:116
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:523
armarx::XMLStateTemplate
Class for legacy to stay compatible with old statecharts.
Definition: XMLState.h:137
armarx::MotionControlGroup::MotionControlGroupStatechartContext::getRobotStateComponent
RobotStateComponentInterfacePrx getRobotStateComponent()
Definition: MotionControlGroupStatechartContext.h:96
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:177
armarx::NJointTaskSpaceDMPControllerMode::CartesianSelection
CartesianSelection
Definition: ControllerInterface.ice:34
armarx::MotionControlGroup::CartesianPositionControlIK::CreateInstance
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Definition: CartesianPositionControlIK.cpp:245
armarx::channels::KinematicUnitObserver::jointVelocities
const KinematicUnitDatafieldCreator jointVelocities("jointVelocities")
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:65
CartesianPositionControlIK.h
CMakePackageFinder.h
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::MotionControlGroup::CartesianPositionControlIK::onEnter
void onEnter() override
Definition: CartesianPositionControlIK.cpp:54
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
RobotStatechartContext.h