TaskspaceMixedImpedanceVelocityController.cpp
Go to the documentation of this file.
2 
3 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
4 #include <VirtualRobot/MathTools.h>
5 
7 
9 
10 #include "../utils.h"
11 
13 {
14 
15  void
17  const VirtualRobot::RobotNodeSetPtr& rns,
18  const VirtualRobot::RobotNodeSetPtr& rtRns,
19  const std::vector<size_t>& torqueControlledIndex,
20  const std::vector<size_t>& velocityControlledIndex)
21  {
23  numOfJoints = rns->getSize();
24 
25  jointIDTorqueMode = torqueControlledIndex;
26  jointIDVelocityMode = velocityControlledIndex;
30 
31  tcp = rns->getTCP();
32  rtTCP = rtRns->getTCP();
34  ik.reset(new VirtualRobot::DifferentialIK(
35  rtRns, rtRns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
36 
38  }
39 
40  void
42  const VirtualRobot::RobotNodeSetPtr& rns)
43  {
44  }
45 
46  void
48  {
49  ftsensor.reset();
50  }
51 
52  bool
54  const std::vector<std::string>& nameList,
55  const std::map<std::string, std::string>& jointControlModeMap)
56  {
57  std::set<std::string> validModes = {"velocity", "torque"};
58 
59  for (const auto& pair : jointControlModeMap)
60  {
61  if (std::find(nameList.begin(), nameList.end(), pair.first) == nameList.end())
62  {
63  ARMARX_ERROR << "TaskspaceMixedImpedanceVelocityController: joint name '"
64  << pair.first << "' not found in robot node set.";
65  return false;
66  }
67 
68  if (validModes.find(pair.second) == validModes.end())
69  {
71  << "TaskspaceMixedImpedanceVelocityController: Invalid control mode for joint '"
72  << pair.first << "': " << pair.second << std::endl;
73  return false;
74  }
75  }
76 
77  return true;
78  }
79 
80  // void
81  // TaskspaceMixedImpedanceVelocityController::updateFT(const FTConfig& c, RtStatus& rtStatus)
82  // {
83  // /// run in rt thread
84  // ftsensor.updateStatus();
85  // if (c.reCalibrate)
86  // {
87  // ftsensor.calibrated.store(false);
88  // /// TODO how to toggle recalibration?
89  // }
90  // ftsensor.compensateTCPGravity(c);
91  // if (!ftsensor.calibrated.load())
92  // {
93  // if (ftsensor.calibrate(c, rtStatus.deltaT))
94  // {
95  // ftsensor.calibrated.store(true);
96  // }
97  // }
98  // else
99  // {
100  // rtStatus.currentForceTorque = ftsensor.getFilteredForceTorque(c);
101  // }
102  // }
103 
104  void
106  {
107  /// run in rt thread
108  rtStatus.currentPose = rtTCP->getPoseInRootFrame();
109 
110  /// ---------------------------- safety guard by FT and target pose ------------------------
111  rtStatus.poseDiffMatImp =
112  c.desiredPose.block<3, 3>(0, 0) * rtStatus.currentPose.block<3, 3>(0, 0).transpose();
113  rtStatus.oriDiffAngleAxis.fromRotationMatrix(rtStatus.poseDiffMatImp);
114 
115  /// this should not be moved to non rt, just in case non rt thread dies, rt still functions as safely
116  if (not ftsensor.isSafe(c.ftConfig))
117  {
118  ARMARX_INFO << "FTGuard indicates RT not safe";
119  c.desiredPose = rtStatus.desiredPose;
120  rtStatus.rtSafe = false;
121  rtStatus.rtTargetSafe = true;
122  }
123  else if ((c.desiredPose.block<3, 1>(0, 3) - rtStatus.currentPose.block<3, 1>(0, 3)).norm() >
124  c.safeDistanceMMToGoal or
125  std::fminf(rtStatus.oriDiffAngleAxis.angle(),
126  2 * M_PI - rtStatus.oriDiffAngleAxis.angle()) >
127  VirtualRobot::MathTools::deg2rad(c.safeRotAngleDegreeToGoal))
128  {
129  c.desiredPose = rtStatus.desiredPose;
130  rtStatus.rtSafe = false;
131  rtStatus.rtTargetSafe = false;
132  }
133  else
134  {
135  rtStatus.desiredPose = c.desiredPose;
136  rtStatus.rtSafe = true;
137  rtStatus.rtTargetSafe = true;
138  }
139 
140  /// ------------------------------ compute jacobi ------------------------------------------
141  rtStatus.jacobi =
142  ik->getJacobianMatrix(rtTCP, VirtualRobot::IKSolver::CartesianSelection::All);
143  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jacobi.cols());
144  ARMARX_CHECK_EQUAL(6, rtStatus.jacobi.rows());
145 
146  // rtStatus.jpinv = ik->computePseudoInverseJacobianMatrix(rtStatus.jacobi, lambda);
147  rtStatus.jpinv = ik->computePseudoInverseJacobianMatrix(
148  rtStatus.jacobi, ik->getJacobiRegularization(VirtualRobot::IKSolver::CartesianSelection::All));
149  ARMARX_CHECK_EQUAL(6, rtStatus.jpinv.cols());
150  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jpinv.rows());
151 
152  rtStatus.jacobi.block(0, 0, 3, rtStatus.numJoints) =
153  0.001 * rtStatus.jacobi.block(0, 0, 3, rtStatus.numJoints);
154 
155  rtStatus.jtpinv =
156  ik->computePseudoInverseJacobianMatrix(rtStatus.jacobi.transpose(), lambda);
157  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jtpinv.cols());
158  ARMARX_CHECK_EQUAL(6, rtStatus.jtpinv.rows());
159 
160  /// ------------------------------ update velocity/twist -----------------------------------
161  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jointPos.rows());
162  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.jointVel.rows());
163  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.qvelFiltered.rows());
164 
165  rtStatus.qvelFiltered =
166  (1 - c.qvelFilter) * rtStatus.qvelFiltered + c.qvelFilter * rtStatus.jointVel;
167  rtStatus.currentTwist = rtStatus.jacobi * rtStatus.qvelFiltered;
168 
169  /// ------------------------------------- Impedance control --------------------------------
170  /// calculate pose error between target pose and current pose
171  /// !!! This is very important: you have to keep position and orientation both
172  /// with UI unit (meter, radian) to calculate impedance force.
173 
174  rtStatus.poseDiffMatImp = rtStatus.desiredPose.block<3, 3>(0, 0) *
175  rtStatus.currentPose.block<3, 3>(0, 0).transpose();
176  // rtStatus.poseErrorImp.head(3) = 0.001 * (rtStatus.desiredPose.block<3, 1>(0, 3) -
177  // rtStatus.currentPose.block<3, 1>(0, 3));
178  rtStatus.poseErrorImp.head(3) = (rtStatus.desiredPose.block<3, 1>(0, 3) -
179  rtStatus.currentPose.block<3, 1>(0, 3)); /// in mm
180  rtStatus.poseErrorImp.tail(3) =
181  VirtualRobot::MathTools::eigen3f2rpy(rtStatus.poseDiffMatImp);
182 
183  /// ------------------------------------- Velocity control ---------------------------------------------------
184  /// calculate pose error between target pose and current pose
185  /// !!! This is very important: you have to keep position and orientation both
186  /// with UI unit (meter, radian) to calculate desired Cartesian velocity.
187  rtStatus.cartesianVelTarget = c.kpCartesianVel.cwiseProduct(rtStatus.poseErrorImp) -
188  c.kdCartesianVel.cwiseProduct(rtStatus.currentTwist);
189 
190  rtStatus.poseErrorImp.head(3) *= 0.001;
191  rtStatus.forceImpedance = c.kpImpedance.cwiseProduct(rtStatus.poseErrorImp) -
192  c.kdImpedance.cwiseProduct(rtStatus.currentTwist);
193 
194 
195 
196  /// ----------------------------- Nullspace PD Control --------------------------------------------------
197  ARMARX_CHECK_EQUAL(rtStatus.numJoints, c.kpNullspaceTorque.rows());
198  ARMARX_CHECK_EQUAL(rtStatus.numJoints, c.kdNullspaceTorque.rows());
199  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.nullspaceTorque.rows());
200  ARMARX_CHECK_EQUAL(rtStatus.numJoints, c.kpNullspaceVel.rows());
201  ARMARX_CHECK_EQUAL(rtStatus.numJoints, c.kdNullspaceVel.rows());
202  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.nullspaceVelocity.rows());
203  ARMARX_CHECK_EQUAL(rtStatus.numJoints, c.desiredNullspaceJointAngles.value().size());
204 
205  rtStatus.nullspaceTorque = c.kpNullspaceTorque.cwiseProduct(
206  c.desiredNullspaceJointAngles.value() - rtStatus.jointPos) -
207  c.kdNullspaceTorque.cwiseProduct(rtStatus.jointVel);
208  rtStatus.nullspaceVelocity =
209  c.kpNullspaceVel.cwiseProduct(c.desiredNullspaceJointAngles.value() -
210  rtStatus.jointPos) -
211  c.kdNullspaceVel.cwiseProduct(rtStatus.qvelFiltered);
212 
213  /// ----------------------------- Map TS target force/velocity to JS --------------------------------------------------
214  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.desiredJointTorques.rows());
215  ARMARX_CHECK_EQUAL(rtStatus.numJoints, rtStatus.desiredJointVelocity.rows());
216  rtStatus.desiredJointTorques =
217  rtStatus.jacobi.transpose() * rtStatus.forceImpedance +
218  (I - rtStatus.jacobi.transpose() * rtStatus.jtpinv) * rtStatus.nullspaceTorque;
219  rtStatus.desiredJointVelocity =
220  rtStatus.jpinv * rtStatus.cartesianVelTarget +
221  (I - rtStatus.jpinv * rtStatus.jacobi) * rtStatus.nullspaceVelocity;
222 
223  /// ----------------------------- write torque target -------------------------------------
224  for (int i = 0; i < rtStatus.desiredJointTorques.rows(); ++i)
225  {
226  rtStatus.desiredJointTorques(i) =
227  std::clamp(rtStatus.desiredJointTorques(i), -c.torqueLimit, c.torqueLimit);
228  }
229  for (int i = 0; i < rtStatus.desiredJointVelocity.rows(); ++i)
230  {
231  rtStatus.desiredJointVelocity(i) =
232  std::clamp(rtStatus.desiredJointVelocity(i), -c.velocityLimit, c.velocityLimit);
233  }
234  }
235 
236  void
238  const size_t numDoFTorque,
239  const size_t numDoFVelocity)
240  {
241  /// This function can be called before the RT thread.
242  /// base
243  jointPosition.resize(nDoF, 0.);
244  jointVelocity.resize(nDoF, 0.);
245  jointTorque.resize(nDoF, 0.);
246  jointPos.setZero(nDoF);
247  jointVel.setZero(nDoF);
248  jointTor.setZero(nDoF);
249  deltaT = 0.0;
250  numJoints = nDoF;
251  nDoFTorque = numDoFTorque;
252  nDoFVelocity = numDoFVelocity;
254 
255  /// targets
256  desiredJointTorques.setZero(nDoF);
257  desiredJointVelocity.setZero(nDoF);
258  cartesianVelTarget.setZero();
259  nullspaceTorque.setZero(nDoF);
260  nullspaceVelocity.setZero(nDoF);
261 
262  /// force torque
263  currentForceTorque.setZero();
264 
265  /// task space variables
266  forceImpedance.setZero();
267 
268  /// current status
269  qvelFiltered.setZero(nDoF);
270  currentPose.setZero();
271  currentTwist.setZero();
272  desiredPose.setZero();
273 
274  /// intermediate results
275  poseDiffMatImp.setZero();
276  poseErrorImp.setZero();
278 
279  /// others
280  jacobi.setZero(6, nDoF);
281  jtpinv.setZero(6, nDoF);
282  jpinv.setZero(nDoF, 6);
283  rtSafe = false;
284  rtTargetSafe = true;
285  }
286 
287  void
289  const Eigen::Matrix4f& currentTCPPose)
290  {
291  /// !!!! TO BE UPDATED IN PREACTIVATE !!!!
292  /// only then the up-to-date robot joint information is available
293  currentPose = currentTCPPose;
294  desiredPose = currentTCPPose;
295  }
296 
297 } // namespace armarx::control::common::control_law
armarx::control::common::control_law::RobotStatus::jointTor
Eigen::VectorXf jointTor
Definition: common.h:37
TaskspaceMixedImpedanceVelocityController.h
armarx::control::common::ft::FTSensor::isSafe
bool isSafe(const FTConfig &c)
Definition: FTSensor.cpp:192
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::desiredPose
Eigen::Matrix4f desiredPose
Definition: TaskspaceMixedImpedanceVelocityController.h:71
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::rtSafe
bool rtSafe
Definition: TaskspaceMixedImpedanceVelocityController.h:82
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::jointIDTorqueMode
std::vector< size_t > jointIDTorqueMode
Definition: TaskspaceMixedImpedanceVelocityController.h:111
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::poseErrorImp
Eigen::Vector6f poseErrorImp
Definition: TaskspaceMixedImpedanceVelocityController.h:75
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::forceImpedance
Eigen::Vector6f forceImpedance
task space variables
Definition: TaskspaceMixedImpedanceVelocityController.h:62
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::jointIDVelocityMode
std::vector< size_t > jointIDVelocityMode
Definition: TaskspaceMixedImpedanceVelocityController.h:112
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::ftsensor
common::ft::FTSensor ftsensor
Definition: TaskspaceMixedImpedanceVelocityController.h:109
armarx::control::common::control_law::RobotStatus::jointTorque
std::vector< float > jointTorque
Definition: common.h:34
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::oriDiffAngleAxis
Eigen::AngleAxisf oriDiffAngleAxis
Definition: TaskspaceMixedImpedanceVelocityController.h:76
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::TaskspaceMixedImpedanceVelocityController::preactivateInit
void preactivateInit(const VirtualRobot::RobotNodeSetPtr &rns)
Definition: TaskspaceMixedImpedanceVelocityController.cpp:41
armarx::control::common::control_law::RobotStatus::jointPos
Eigen::VectorXf jointPos
Definition: common.h:35
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::currentTwist
Eigen::Vector6f currentTwist
Definition: TaskspaceMixedImpedanceVelocityController.h:70
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::tcp
VirtualRobot::RobotNodePtr tcp
Definition: TaskspaceMixedImpedanceVelocityController.h:107
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::nDoFTorque
size_t nDoFTorque
Definition: TaskspaceMixedImpedanceVelocityController.h:94
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::nullspaceVelocity
Eigen::VectorXf nullspaceVelocity
Definition: TaskspaceMixedImpedanceVelocityController.h:56
armarx::control::common::control_law::RobotStatus::jointVelocity
std::vector< float > jointVelocity
Definition: common.h:33
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::poseDiffMatImp
Eigen::Matrix3f poseDiffMatImp
intermediate results
Definition: TaskspaceMixedImpedanceVelocityController.h:74
device.h
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::nDoFVelocity
size_t nDoFVelocity
Definition: TaskspaceMixedImpedanceVelocityController.h:86
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:125
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::currentPose
Eigen::Matrix4f currentPose
Definition: TaskspaceMixedImpedanceVelocityController.h:69
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::firstRun
void firstRun()
Definition: TaskspaceMixedImpedanceVelocityController.cpp:47
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:523
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::rtTargetSafe
bool rtTargetSafe
Definition: TaskspaceMixedImpedanceVelocityController.h:83
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::isControlModeValid
bool isControlModeValid(const std::vector< std::string > &nameList, const std::map< std::string, std::string > &jointControlModeMap)
Definition: TaskspaceMixedImpedanceVelocityController.cpp:53
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::rtPreActivate
void rtPreActivate(const Eigen::Matrix4f &currentPose)
Definition: TaskspaceMixedImpedanceVelocityController.cpp:288
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::Config
common::control_law::arondto::TaskspaceMixedImpedanceVelocityControllerConfig Config
Definition: TaskspaceMixedImpedanceVelocityController.h:45
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::desiredJointVelocity
Eigen::VectorXf desiredJointVelocity
Definition: TaskspaceMixedImpedanceVelocityController.h:54
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus
internal status of the controller, containing intermediate variables, mutable targets
Definition: TaskspaceMixedImpedanceVelocityController.h:50
armarx::control::common::control_law::RobotStatus::jointVel
Eigen::VectorXf jointVel
Definition: common.h:36
armarx::control::common::control_law
This file is part of ArmarX.
Definition: aron_conversions.cpp:68
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::jpinv
Eigen::MatrixXf jpinv
Definition: TaskspaceMixedImpedanceVelocityController.h:81
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::reset
void reset(const unsigned int nDoF, const size_t numDoFTorque, const size_t numDoFVelocity)
Definition: TaskspaceMixedImpedanceVelocityController.cpp:237
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::desiredJointTorques
Eigen::VectorXf desiredJointTorques
targets
Definition: TaskspaceMixedImpedanceVelocityController.h:53
armarx::control::common::ft::FTSensor::reset
void reset()
Definition: FTSensor.cpp:87
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::nDoFVelocity
size_t nDoFVelocity
Definition: TaskspaceMixedImpedanceVelocityController.h:95
armarx::control::common::control_law::RobotStatus::jointPosition
std::vector< float > jointPosition
Definition: common.h:32
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::run
void run(Config &c, RtStatus &robotStatus)
Definition: TaskspaceMixedImpedanceVelocityController.cpp:105
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::initialize
void initialize(const VirtualRobot::RobotNodeSetPtr &rns, const VirtualRobot::RobotNodeSetPtr &rtRns, const std::vector< size_t > &torqueControlledIndex, const std::vector< size_t > &velocityControlledIndex)
Definition: TaskspaceMixedImpedanceVelocityController.cpp:16
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::jtpinv
Eigen::MatrixXf jtpinv
Definition: TaskspaceMixedImpedanceVelocityController.h:80
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::rtTCP
VirtualRobot::RobotNodePtr rtTCP
Definition: TaskspaceMixedImpedanceVelocityController.h:108
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::nullspaceTorque
Eigen::VectorXf nullspaceTorque
Definition: TaskspaceMixedImpedanceVelocityController.h:55
ControlThreadOutputBuffer.h
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::jacobi
Eigen::MatrixXf jacobi
others
Definition: TaskspaceMixedImpedanceVelocityController.h:79
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::qvelFiltered
Eigen::VectorXf qvelFiltered
Definition: TaskspaceMixedImpedanceVelocityController.h:68
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::transpose
std::vector< std::vector< T > > transpose(const std::vector< std::vector< T >> &src, Thrower thrower)
Definition: SimoxCSpace.cpp:706
armarx::control::common::control_law::RobotStatus::numJoints
unsigned int numJoints
Definition: common.h:39
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::cartesianVelTarget
Eigen::Vector6f cartesianVelTarget
Definition: TaskspaceMixedImpedanceVelocityController.h:63
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::nDoFTorque
size_t nDoFTorque
Definition: TaskspaceMixedImpedanceVelocityController.h:85
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::numOfJoints
unsigned int numOfJoints
Definition: TaskspaceMixedImpedanceVelocityController.h:93
armarx::control::common::control_law::RobotStatus::deltaT
double deltaT
Definition: common.h:38
armarx::control::common::control_law::TaskspaceMixedImpedanceVelocityController::RtStatus::currentForceTorque
Eigen::Vector6f currentForceTorque
force torque
Definition: TaskspaceMixedImpedanceVelocityController.h:59