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