TaskspaceAdmittanceController.cpp
Go to the documentation of this file.
2 
3 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
4 #include <VirtualRobot/IK/DifferentialIK.h>
5 #include <VirtualRobot/IK/JacobiProvider.h>
6 #include <VirtualRobot/MathTools.h>
7 #include <VirtualRobot/Nodes/RobotNode.h>
8 #include <VirtualRobot/Robot.h>
9 #include <VirtualRobot/RobotNodeSet.h>
10 
14 
16 
17 #include "../utils.h"
18 
20 {
21 
22  void
23  TaskspaceAdmittanceController::initialize(const VirtualRobot::RobotNodeSetPtr& rns,
24  const VirtualRobot::RobotNodeSetPtr& rtRns)
25  {
27  tcp = rns->getTCP();
28  rtTCP = rtRns->getTCP();
30  ik.reset(new VirtualRobot::DifferentialIK(
31  rtRns, rtRns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
32 
33  numOfJoints = rns->getSize();
35  }
36 
37  void
38  TaskspaceAdmittanceController::preactivateInit(const VirtualRobot::RobotNodeSetPtr& rns)
39  {
40  }
41 
42  void
44  {
45  ftsensor.reset();
46  }
47 
48  // void
49  // TaskspaceAdmittanceController::updateFT(const FTConfig& c, RtStatus& rtStatus)
50  // {
51  // /// run in rt thread
52  // ftsensor.updateStatus();
53  // if (c.reCalibrate)
54  // {
55  // ftsensor.calibrated.store(false);
56  // /// TODO how to toggle recalibration?
57  // }
58  // ftsensor.compensateTCPGravity(c);
59  // if (!ftsensor.calibrated.load())
60  // {
61  // if (ftsensor.calibrate(c, rtStatus.deltaT))
62  // {
63  // ftsensor.calibrated.store(true);
64  // }
65  // }
66  // else
67  // {
68  // rtStatus.currentForceTorque = ftsensor.getFilteredForceTorque(c);
69  // }
70  // }
71 
72  void
74  {
75  /// run in rt thread
76  rtStatus.currentPose = rtTCP->getPoseInRootFrame();
77 
78  /// ---------------------------- safety guard by FT and target pose ------------------------
79  rtStatus.poseDiffMatImp =
80  c.desiredPose.block<3, 3>(0, 0) * rtStatus.currentPose.block<3, 3>(0, 0).transpose();
81  rtStatus.oriDiffAngleAxis.fromRotationMatrix(rtStatus.poseDiffMatImp);
82 
83  /// this should not be moved to non rt, just in case non rt thread dies, rt still functions as safely
84  if (not ftsensor.isSafe(c.ftConfig))
85  {
86  ARMARX_INFO << "FTGuard indicates RT not safe";
87  c.desiredPose = rtStatus.desiredPose;
88  rtStatus.rtSafe = false;
89  rtStatus.rtTargetSafe = true;
90  }
91  else if (ftsensor.calibrated.load())
92  {
93  if ((c.desiredPose.block<3, 1>(0, 3) - rtStatus.currentPose.block<3, 1>(0, 3)).norm() >
94  c.safeDistanceMMToGoal or
95  std::fminf(rtStatus.oriDiffAngleAxis.angle(),
96  2 * M_PI - rtStatus.oriDiffAngleAxis.angle()) >
97  VirtualRobot::MathTools::deg2rad(c.safeRotAngleDegreeToGoal))
98  {
99  c.desiredPose = rtStatus.desiredPose;
100  rtStatus.rtSafe = false;
101  rtStatus.rtTargetSafe = false;
102  }
103  else
104  {
105  rtStatus.desiredPose = c.desiredPose;
106  rtStatus.rtSafe = true;
107  rtStatus.rtTargetSafe = true;
108  }
109  }
110  else
111  {
112  ARMARX_RT_LOGF_WARN("not initialized or ft sensor not calibrated!");
113  c.desiredTwist.setZero();
114  c.kmAdmittance.setZero();
115  }
116 
117  /// ------------------------------ compute jacobi ------------------------------------------
118  rtStatus.jacobi =
119  ik->getJacobianMatrix(rtTCP, VirtualRobot::IKSolver::CartesianSelection::All);
120  rtStatus.jacobi.block(0, 0, 3, rtStatus.numJoints) =
121  0.001 * rtStatus.jacobi.block(0, 0, 3, rtStatus.numJoints);
122  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jacobi.cols());
123  ARMARX_CHECK_EQUAL(6, rtStatus.jacobi.rows());
124 
125  rtStatus.jtpinv =
126  ik->computePseudoInverseJacobianMatrix(rtStatus.jacobi.transpose(), lambda);
127  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jtpinv.cols());
128  ARMARX_CHECK_EQUAL(6, rtStatus.jtpinv.rows());
129 
130  /// ------------------------------ update velocity/twist -----------------------------------
131  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jointPos.rows());
132  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jointVel.rows());
133  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.qvelFiltered.rows());
134 
135  rtStatus.qvelFiltered =
136  (1 - c.qvelFilter) * rtStatus.qvelFiltered + c.qvelFilter * rtStatus.jointVel;
137  rtStatus.currentTwist = rtStatus.jacobi * rtStatus.qvelFiltered;
138 
139  /// ---------------------------- admittance control ---------------------------------------------
140  /// calculate pose error between the virtual pose and the target pose
141  rtStatus.poseDiffMatAdm = rtStatus.virtualPose.block<3, 3>(0, 0) *
142  rtStatus.desiredPose.block<3, 3>(0, 0).transpose();
143  rtStatus.poseErrorAdm.head<3>() =
144  rtStatus.virtualPose.block<3, 1>(0, 3) - rtStatus.desiredPose.block<3, 1>(0, 3);
145  rtStatus.poseErrorAdm.tail<3>() =
146  VirtualRobot::MathTools::eigen3f2rpy(rtStatus.poseDiffMatAdm);
147 
148  /// admittance control law and Euler Integration -> virtual pose
149  rtStatus.acc = c.kmAdmittance.cwiseProduct(rtStatus.currentForceTorque) -
150  c.kpAdmittance.cwiseProduct(rtStatus.poseErrorAdm) -
151  c.kdAdmittance.cwiseProduct(rtStatus.virtualVel);
152 
153  rtStatus.vel =
154  rtStatus.virtualVel + 0.5 * rtStatus.deltaT * (rtStatus.acc + rtStatus.virtualAcc);
155  rtStatus.pos = 0.5 * rtStatus.deltaT * (rtStatus.vel + rtStatus.virtualVel);
156  rtStatus.virtualAcc = rtStatus.acc;
157  rtStatus.virtualVel = rtStatus.vel;
158 
159  rtStatus.virtualPose.block<3, 1>(0, 3) += rtStatus.pos.head<3>();
160  rtStatus.virtualPose.block<3, 3>(0, 0) =
161  VirtualRobot::MathTools::rpy2eigen3f(
162  rtStatus.pos(3), rtStatus.pos(4), rtStatus.pos(5)) *
163  rtStatus.virtualPose.block<3, 3>(0, 0);
164 
165  /// ------------------------------------- Impedance control --------------------------------
166  /// calculate pose error between target pose and current pose
167  /// !!! This is very important: you have to keep postion and orientation both
168  /// with UI unit (meter, radian) to calculate impedance force.
169 
170  rtStatus.poseDiffMatImp = rtStatus.desiredPose.block<3, 3>(0, 0) *
171  rtStatus.currentPose.block<3, 3>(0, 0).transpose();
172  rtStatus.poseErrorImp.head<3>() = 0.001 * (rtStatus.desiredPose.block<3, 1>(0, 3) -
173  rtStatus.currentPose.block<3, 1>(0, 3));
174  rtStatus.poseErrorImp.tail<3>() =
175  VirtualRobot::MathTools::eigen3f2rpy(rtStatus.poseDiffMatImp);
176 
177  rtStatus.forceImpedance = c.kpImpedance.cwiseProduct(rtStatus.poseErrorImp) -
178  c.kdImpedance.cwiseProduct(rtStatus.currentTwist);
179 
180  /// ----------------------------- Nullspace PD Control -------------------------------------
181  ARMARX_CHECK_EQUAL(rtStatus.numJoints, c.kpNullspace.rows());
182  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.nullspaceTorque.rows());
183  ARMARX_CHECK_EQUAL(rtStatus.numJoints, c.desiredNullspaceJointAngles.value().size());
184  rtStatus.nullspaceTorque =
185  c.kpNullspace.cwiseProduct(c.desiredNullspaceJointAngles.value() - rtStatus.jointPos) -
186  c.kdNullspace.cwiseProduct(rtStatus.qvelFiltered);
187 
188  /// ----------------------------- Map TS target force to JS --------------------------------
189  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.desiredJointTorques.rows());
190  rtStatus.desiredJointTorques =
191  rtStatus.jacobi.transpose() * rtStatus.forceImpedance +
192  (I - rtStatus.jacobi.transpose() * rtStatus.jtpinv) * rtStatus.nullspaceTorque;
193 
194  /// ----------------------------- write torque target -------------------------------------
195  for (int i = 0; i < rtStatus.desiredJointTorques.rows(); ++i)
196  {
197  rtStatus.desiredJointTorques(i) =
198  std::clamp(rtStatus.desiredJointTorques(i), -c.torqueLimit, c.torqueLimit);
199  }
200  }
201 
202  void
204  {
205  /// This function can be called before the RT thread.
206  /// base
207  jointPosition.resize(nDoF, 0.);
208  jointVelocity.resize(nDoF, 0.);
209  jointTorque.resize(nDoF, 0.);
210  jointPos.setZero(nDoF);
211  jointVel.setZero(nDoF);
212  jointTor.setZero(nDoF);
213  deltaT = 0.0;
214  accumulateTime = 0.0;
215  numJoints = nDoF;
216 
217  /// targets
218  desiredJointTorques.setZero(nDoF);
219  nullspaceTorque.setZero(nDoF);
220 
221  /// force torque
222  currentForceTorque.setZero();
223 
224  /// task space variables
225  forceImpedance.setZero();
226 
227  /// current status
228  qvelFiltered.setZero(nDoF);
229  currentPose.setZero();
230  currentTwist.setZero();
231  desiredPose.setZero();
232 
233  /// virtual status
234  virtualPose.setZero();
235  virtualVel.setZero();
236  virtualAcc.setZero();
237 
238  /// intermediate results
239  poseDiffMatImp.setZero();
240  poseDiffMatAdm.setZero();
241  poseErrorImp.setZero();
242  poseErrorAdm.setZero();
244  ARMARX_INFO << "------ " << VAROUT(oriDiffAngleAxis.angle());
245 
246  /// others
247  jacobi.setZero(6, nDoF);
248  jtpinv.setZero(6, nDoF);
249  rtSafe = false;
250  rtTargetSafe = true;
251  }
252 
253  void
255  {
256  /// !!!! TO BE UPDATED IN PREACTIVATE !!!!
257  /// only then the up-to-date robot joint information is available
258  currentPose = currentTCPPose;
259  desiredPose = currentTCPPose;
260  accumulateTime = 0.0;
261  }
262 
263 } // namespace armarx::control::common::control_law
armarx::control::common::control_law::RobotStatus::jointTor
Eigen::VectorXf jointTor
Definition: common.h:40
armarx::control::common::control_law::TaskspaceAdmittanceController::Config
common::control_law::arondto::TaskspaceAdmittanceControllerConfig Config
Definition: TaskspaceAdmittanceController.h:40
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus
internal status of the controller, containing intermediate variables, mutable targets
Definition: TaskspaceAdmittanceController.h:44
armarx::control::common::control_law::TaskspaceAdmittanceController::rtTCP
VirtualRobot::RobotNodePtr rtTCP
Definition: TaskspaceAdmittanceController.h:102
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::rtPreActivate
void rtPreActivate(const Eigen::Matrix4f &currentPose)
Definition: TaskspaceAdmittanceController.cpp:254
armarx::control::common::control_law::TaskspaceAdmittanceController::firstRun
void firstRun()
Definition: TaskspaceAdmittanceController.cpp:43
armarx::control::common::ft::FTSensor::isSafe
bool isSafe(const FTConfig &c)
Definition: FTSensor.cpp:198
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::virtualVel
Eigen::Vector6f virtualVel
Definition: TaskspaceAdmittanceController.h:52
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::nullspaceTorque
Eigen::VectorXf nullspaceTorque
Definition: TaskspaceAdmittanceController.h:48
armarx::control::common::control_law::RobotStatus::jointTorque
std::vector< float > jointTorque
Definition: common.h:37
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::reset
void reset(const unsigned int nDoF)
Definition: TaskspaceAdmittanceController.cpp:203
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::control::common::control_law::RobotStatus::jointPos
Eigen::VectorXf jointPos
Definition: common.h:38
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::poseErrorAdm
Eigen::Vector6f poseErrorAdm
Definition: TaskspaceAdmittanceController.h:56
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::control::common::control_law::RobotStatus::jointVelocity
std::vector< float > jointVelocity
Definition: common.h:36
armarx::control::common::control_law::TaskspaceAdmittanceController::ftsensor
common::ft::FTSensor ftsensor
Definition: TaskspaceAdmittanceController.h:103
device.h
armarx::control::common::control_law::TaskspaceAdmittanceController::numOfJoints
unsigned int numOfJoints
Definition: TaskspaceAdmittanceController.h:90
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::currentPose
Eigen::Matrix4f currentPose
Definition: TaskspaceAdmittanceController.h:71
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:136
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::forceImpedance
Eigen::Vector6f forceImpedance
task space variables
Definition: TaskspaceAdmittanceController.h:65
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::currentTwist
Eigen::Vector6f currentTwist
Definition: TaskspaceAdmittanceController.h:72
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::jtpinv
Eigen::MatrixXf jtpinv
Definition: TaskspaceAdmittanceController.h:82
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::oriDiffAngleAxis
Eigen::AngleAxisf oriDiffAngleAxis
Definition: TaskspaceAdmittanceController.h:78
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::control::common::control_law::TaskspaceAdmittanceController::preactivateInit
void preactivateInit(const VirtualRobot::RobotNodeSetPtr &rns)
Definition: TaskspaceAdmittanceController.cpp:38
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::virtualPose
Eigen::Matrix4f virtualPose
variables that need to be kept locally by the rt thread
Definition: TaskspaceAdmittanceController.h:51
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::poseErrorImp
Eigen::Vector6f poseErrorImp
Definition: TaskspaceAdmittanceController.h:77
armarx::control::common::control_law::RobotStatus::jointVel
Eigen::VectorXf jointVel
Definition: common.h:39
armarx::control::common::control_law::TaskspaceAdmittanceController::run
void run(Config &c, RtStatus &robotStatus)
Definition: TaskspaceAdmittanceController.cpp:73
armarx::control::common::ft::FTSensor::calibrated
std::atomic_bool calibrated
Definition: FTSensor.h:76
armarx::control::common::control_law
This file is part of ArmarX.
Definition: aron_conversions.cpp:68
ControlTarget1DoFActuator.h
armarx::control::common::ft::FTSensor::reset
void reset()
Definition: FTSensor.cpp:91
TaskspaceAdmittanceController.h
armarx::control::common::control_law::RobotStatus::jointPosition
std::vector< float > jointPosition
Definition: common.h:35
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::acc
Eigen::Vector6f acc
Definition: TaskspaceAdmittanceController.h:57
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::qvelFiltered
Eigen::VectorXf qvelFiltered
Definition: TaskspaceAdmittanceController.h:70
for
for(;yybottom<=yytop;yybottom++)
Definition: Grammar.cpp:705
armarx::control::common::control_law::TaskspaceAdmittanceController::tcp
VirtualRobot::RobotNodePtr tcp
Definition: TaskspaceAdmittanceController.h:101
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::rtSafe
bool rtSafe
Definition: TaskspaceAdmittanceController.h:83
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::currentForceTorque
Eigen::Vector6f currentForceTorque
force torque
Definition: TaskspaceAdmittanceController.h:62
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::virtualAcc
Eigen::Vector6f virtualAcc
Definition: TaskspaceAdmittanceController.h:53
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::poseDiffMatAdm
Eigen::Matrix3f poseDiffMatAdm
Definition: TaskspaceAdmittanceController.h:55
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::pos
Eigen::Vector6f pos
Definition: TaskspaceAdmittanceController.h:59
ControlThreadOutputBuffer.h
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::poseDiffMatImp
Eigen::Matrix3f poseDiffMatImp
intermediate results
Definition: TaskspaceAdmittanceController.h:76
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::desiredJointTorques
Eigen::VectorXf desiredJointTorques
targets
Definition: TaskspaceAdmittanceController.h:47
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
ARMARX_RT_LOGF_WARN
#define ARMARX_RT_LOGF_WARN(...)
Definition: ControlThreadOutputBuffer.h:350
armarx::transpose
std::vector< std::vector< T > > transpose(const std::vector< std::vector< T >> &src, Thrower thrower)
Definition: SimoxCSpace.cpp:772
armarx::control::common::control_law::RobotStatus::numJoints
unsigned int numJoints
Definition: common.h:43
armarx::control::common::control_law::TaskspaceAdmittanceController::initialize
void initialize(const VirtualRobot::RobotNodeSetPtr &rns, const VirtualRobot::RobotNodeSetPtr &rtRns)
Definition: TaskspaceAdmittanceController.cpp:23
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::desiredPose
Eigen::Matrix4f desiredPose
Definition: TaskspaceAdmittanceController.h:73
armarx::control::common::control_law::RobotStatus::accumulateTime
double accumulateTime
Definition: common.h:42
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::rtTargetSafe
bool rtTargetSafe
Definition: TaskspaceAdmittanceController.h:84
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::vel
Eigen::Vector6f vel
Definition: TaskspaceAdmittanceController.h:58
SensorValue1DoFActuator.h
armarx::control::common::control_law::RobotStatus::deltaT
double deltaT
Definition: common.h:41
armarx::control::common::control_law::TaskspaceAdmittanceController::RtStatus::jacobi
Eigen::MatrixXf jacobi
others
Definition: TaskspaceAdmittanceController.h:81