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