CartesianImpedanceController.cpp
Go to the documentation of this file.
1 
3 
4 #include <algorithm>
5 
6 #include <SimoxUtility/math/compare/is_equal.h>
7 #include <SimoxUtility/math/convert/mat4f_to_pos.h>
8 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
9 #include <VirtualRobot/IK/DifferentialIK.h>
10 #include <VirtualRobot/IK/IKSolver.h>
11 #include <VirtualRobot/MathTools.h>
12 #include <VirtualRobot/Nodes/RobotNode.h>
13 #include <VirtualRobot/Robot.h>
14 #include <VirtualRobot/RobotNodeSet.h>
15 
18 
19 using namespace armarx;
20 
21 int
23 {
24  return targetJointTorques.size();
25 }
26 
27 void
28 CartesianImpedanceController::initialize(const VirtualRobot::RobotNodeSetPtr& rns)
29 {
31  tcp = rns->getTCP();
33  ik.reset(new VirtualRobot::DifferentialIK(
34  rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
35 
36  const auto size = rns->getSize();
37  qpos.resize(size);
38  qvel.resize(size);
39  tcptwist.resize(size);
40  nullqerror.resize(size);
41  nullspaceTorque.resize(size);
42  targetJointTorques.resize(size);
43 
44  I = Eigen::MatrixXf::Identity(size, size);
45 }
46 
47 const Eigen::VectorXf&
49  const Config& cfg,
50  std::vector<const SensorValue1DoFActuatorTorque*> torqueSensors,
51  std::vector<const SensorValue1DoFActuatorVelocity*> velocitySensors,
52  std::vector<const SensorValue1DoFActuatorPosition*> positionSensors)
53 {
55  simox::math::is_equal(bufferSize(), cfg.Knull.size())); ///TODO move this to core
56  ARMARX_CHECK_EXPRESSION(simox::math::is_equal(bufferSize(), cfg.Dnull.size()));
57  ARMARX_CHECK_EXPRESSION(simox::math::is_equal(bufferSize(), cfg.desiredJointPosition.size()));
59 
60  ARMARX_CHECK_EXPRESSION(simox::math::is_equal(bufferSize(), torqueSensors.size()));
61  ARMARX_CHECK_EXPRESSION(simox::math::is_equal(bufferSize(), velocitySensors.size()));
62  ARMARX_CHECK_EXPRESSION(simox::math::is_equal(bufferSize(), positionSensors.size()));
63 
64  const Eigen::MatrixXf jacobi = ik->getJacobianMatrix(
65  tcp, VirtualRobot::IKSolver::CartesianSelection::All); ///TODO output param version
66  ARMARX_CHECK_EXPRESSION(simox::math::is_equal(bufferSize(), jacobi.cols()));
67  ARMARX_CHECK_EXPRESSION(simox::math::is_equal(6, jacobi.rows()));
68  const Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(
69  jacobi.transpose(), lambda); ///TODO output param version
70 
71  for (size_t i = 0; i < velocitySensors.size(); ++i)
72  {
73  qpos(i) = positionSensors[i]->position;
74  qvel(i) = velocitySensors[i]->velocity;
75  }
76 
77  const Eigen::Vector6f tcptwist = jacobi * qvel;
78 
79  const Eigen::Vector3f currentTCPLinearVelocity{
80  0.001f * tcptwist(0), 0.001f * tcptwist(1), 0.001f * tcptwist(2)};
81  const Eigen::Vector3f currentTCPAngularVelocity{tcptwist(3), tcptwist(4), tcptwist(5)};
82 
83  const Eigen::Vector3f currentTCPPosition = tcp->getPositionInRootFrame();
84  const Eigen::Vector3f tcpForces =
85  0.001 * cfg.Kpos.cwiseProduct(cfg.desiredPosition - currentTCPPosition);
86  const Eigen::Vector3f tcpDesiredForce =
87  tcpForces - cfg.Dpos.cwiseProduct(currentTCPLinearVelocity);
88 
89  const Eigen::Matrix4f currentTCPPose = tcp->getPoseInRootFrame();
90  const Eigen::Matrix3f currentRotMat = currentTCPPose.block<3, 3>(0, 0);
91  const Eigen::Matrix3f desiredMat(cfg.desiredOrientation);
92  const Eigen::Matrix3f diffMat = desiredMat * currentRotMat.inverse();
93  // const Eigen::Quaternionf cquat(currentRotMat);
94  // const Eigen::Quaternionf diffQuaternion = desiredQuaternion * cquat.conjugate();
95  // const Eigen::AngleAxisf angleAxis(diffQuaternion);
96 
97  const Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
98  const Eigen::Vector3f tcpDesiredTorque =
99  cfg.Kori.cwiseProduct(rpy) - cfg.Dori.cwiseProduct(currentTCPAngularVelocity);
100  Eigen::Vector6f tcpDesiredWrench;
101  tcpDesiredWrench << 0.001 * tcpDesiredForce, tcpDesiredTorque;
102 
103  // calculate desired joint torque
104  nullqerror = cfg.desiredJointPosition - qpos;
105 
106  for (int i = 0; i < nullqerror.rows(); ++i)
107  {
108  if (fabs(nullqerror(i)) < 0.09)
109  {
110  nullqerror(i) = 0;
111  }
112  }
113  nullspaceTorque = cfg.Knull.cwiseProduct(nullqerror) - cfg.Dnull.cwiseProduct(qvel);
114 
115  targetJointTorques =
116  jacobi.transpose() * tcpDesiredWrench + (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
117  for (int i = 0; i < targetJointTorques.size(); ++i)
118  {
119  targetJointTorques(i) =
120  std::clamp(targetJointTorques(i), -cfg.torqueLimit, cfg.torqueLimit);
121  }
122  //write debug data
123  {
124  const Eigen::Quaternionf cquat(currentRotMat);
125  dbg.errorAngle = cquat.angularDistance(cfg.desiredOrientation);
126  dbg.posiError = (cfg.desiredPosition - currentTCPPosition).norm();
127  dbg.tcpDesiredForce = tcpDesiredForce;
128  dbg.tcpDesiredTorque = tcpDesiredTorque;
129  }
130 
131  return targetJointTorques;
132 }
armarx::CartesianImpedanceController::Config::Kori
Eigen::Vector3f Kori
Definition: CartesianImpedanceController.h:22
armarx::CartesianImpedanceController::Config::Knull
Eigen::VectorXf Knull
Definition: CartesianImpedanceController.h:24
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::CartesianImpedanceController::Config::desiredJointPosition
Eigen::VectorXf desiredJointPosition
Definition: CartesianImpedanceController.h:26
ARMARX_CHECK_NOT_NULL
#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...
Definition: ExpressionException.h:206
armarx::CartesianImpedanceController::Config::Dnull
Eigen::VectorXf Dnull
Definition: CartesianImpedanceController.h:25
armarx::CartesianImpedanceController::run
const Eigen::VectorXf & run(const Config &cfg, std::vector< const SensorValue1DoFActuatorTorque * > torqueSensors, std::vector< const SensorValue1DoFActuatorVelocity * > velocitySensors, std::vector< const SensorValue1DoFActuatorPosition * > positionSensors)
Definition: CartesianImpedanceController.cpp:48
armarx::CartesianImpedanceController::bufferSize
int bufferSize() const
Definition: CartesianImpedanceController.cpp:22
armarx::CartesianImpedanceController::Config::torqueLimit
float torqueLimit
Definition: CartesianImpedanceController.h:27
armarx::CartesianImpedanceController::Config::Dpos
Eigen::Vector3f Dpos
Definition: CartesianImpedanceController.h:21
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:136
armarx::CartesianImpedanceController::Config::desiredOrientation
Eigen::Quaternionf desiredOrientation
Definition: CartesianImpedanceController.h:19
armarx::CartesianImpedanceController::Config::Dori
Eigen::Vector3f Dori
Definition: CartesianImpedanceController.h:23
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
armarx::CartesianImpedanceController::Config::desiredPosition
Eigen::Vector3f desiredPosition
Definition: CartesianImpedanceController.h:18
ControlTarget1DoFActuator.h
armarx::CartesianImpedanceController::Debug::errorAngle
float errorAngle
Definition: CartesianImpedanceController.h:33
ARMARX_CHECK_GREATER_EQUAL
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
Definition: ExpressionException.h:123
armarx::CartesianImpedanceController::Config
Definition: CartesianImpedanceController.h:16
armarx::CartesianImpedanceController::initialize
void initialize(const VirtualRobot::RobotNodeSetPtr &rns)
Definition: CartesianImpedanceController.cpp:28
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::CartesianImpedanceController::Debug::posiError
float posiError
Definition: CartesianImpedanceController.h:34
armarx::Quaternion< float, 0 >
CartesianImpedanceController.h
armarx::CartesianImpedanceController::Debug::tcpDesiredForce
Eigen::Vector3f tcpDesiredForce
Definition: CartesianImpedanceController.h:35
armarx::CartesianImpedanceController::dbg
Debug dbg
Definition: CartesianImpedanceController.h:55
Eigen::Matrix< float, 6, 1 >
armarx::CartesianImpedanceController::Debug::tcpDesiredTorque
Eigen::Vector3f tcpDesiredTorque
Definition: CartesianImpedanceController.h:36
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:649
armarx::CartesianImpedanceController::Config::Kpos
Eigen::Vector3f Kpos
Definition: CartesianImpedanceController.h:20
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
SensorValue1DoFActuator.h
norm
double norm(const Point &a)
Definition: point.hpp:102