3#include <SimoxUtility/json.h>
4#include <SimoxUtility/math/compare/is_equal.h>
5#include <SimoxUtility/math/convert/mat4f_to_pos.h>
6#include <SimoxUtility/math/convert/mat4f_to_quat.h>
7#include <VirtualRobot/MathTools.h>
8#include <VirtualRobot/Nodes/RobotNode.h>
9#include <VirtualRobot/Nodes/Sensor.h>
10#include <VirtualRobot/RobotNodeSet.h>
27 ARMARX_INFO <<
"--> Initializing force torque sensor " <<
c.sensorName;
28 const SensorValueBase* svlf = robotUnit->getSensorDevice(
c.sensorName)->getSensorValue();
32 sensorNode = rns->getRobot()->getSensor(
c.sensorName)->getRobotNode();
34 if (
c.sensorName ==
"FT R")
36 tcpMass = calibDefaults.tcpMassRight;
37 tcpCoMInFTSensorFrame = calibDefaults.tcpCoMInFTFrameRight;
39 else if (
c.sensorName ==
"FT L")
41 tcpMass = calibDefaults.tcpMassLeft;
42 tcpCoMInFTSensorFrame = calibDefaults.tcpCoMInFTFrameLeft;
47 filteredForce.setZero();
48 filteredTorque.setZero();
49 filteredForceInRoot.setZero();
50 filteredTorqueInRoot.setZero();
52 tcpGravityCompensation.setZero();
53 tcpGravForceVec.setZero();
54 tcpGravTorqueVec.setZero();
56 sensorOriInRoot = Eigen::Matrix3f::Identity();
58 ARMARX_INFO <<
"<-- Force torque sensor initialized.";
97 forceOffset.setZero();
98 torqueOffset.setZero();
102 timeForCalibration = 0.0f;
104 safeGuardForceOffset.setZero();
105 safeGuardTorqueOffset.setZero();
107 safeGuardEnabledForce.store(
false);
108 safeGuardEnabledTorque.store(
false);
110 resetForceGuard.store(
true);
111 resetTorqueGuard.store(
true);
131 sensorOriInRoot = sensorNode->getOrientationInRootFrame();
132 rawForce = forceSensor->force;
133 rawTorque = forceSensor->torque;
158 if (
c.enableSafeGuardForce and resetForceGuard.load())
160 safeGuardForceOffset = filteredForceInRoot;
161 ARMARX_INFO <<
"Resetting force safe guard with baseline "
162 <<
VAROUT(filteredForceInRoot);
164 safeGuardEnabledForce.store(
true);
165 resetForceGuard.store(
false);
167 if (
c.enableSafeGuardTorque and resetTorqueGuard.load())
169 safeGuardTorqueOffset = filteredTorqueInRoot;
171 safeGuardEnabledTorque.store(
true);
172 resetTorqueGuard.store(
false);
179 if (enableForceGuard)
181 resetForceGuard.store(
true);
183 if (enableTorqueGuard)
185 resetTorqueGuard.store(
true);
192 return safeGuardEnabledForce.load();
198 return safeGuardEnabledTorque.load();
205 (
c.enableSafeGuardForce and
206 (filteredForceInRoot - safeGuardForceOffset).norm() >
c.safeGuardForceThreshold) or
207 (
c.enableSafeGuardTorque and
208 (filteredTorqueInRoot - safeGuardTorqueOffset).
norm() >
c.safeGuardTorqueThreshold);
209 ftSafe.store(not unsafeFlag);
223 forceOffset = (1 -
c.ftFilter) * forceOffset +
224 c.ftFilter * (forceSensor->force -
225 sensorOriInRoot.transpose() * tcpGravityCompensation.head<3>());
226 torqueOffset = (1 -
c.ftFilter) * torqueOffset +
227 c.ftFilter * (forceSensor->torque - sensorOriInRoot.transpose() *
228 tcpGravityCompensation.tail<3>());
230 timeForCalibration = timeForCalibration + deltaT;
231 if (timeForCalibration >
c.timeLimit)
236 "FT calibration done \n"
237 "-- force offset: [%.2f, %.2f, %.2f] \n"
238 "-- torque offset: [%.2f, %.2f, %.2f] \n"
239 "-- gravity compensation: [%.2f, %.2f, %.2f, %.2f, %.2f, %.2f]",
246 tcpGravityCompensation(0),
247 tcpGravityCompensation(1),
248 tcpGravityCompensation(2),
249 tcpGravityCompensation(3),
250 tcpGravityCompensation(4),
251 tcpGravityCompensation(5));
279 if (
c.enableTCPGravityCompensation)
282 tcpGravForceVec = tcpMass * gravity.head<3>();
283 tcpGravTorqueVec = (sensorOriInRoot * tcpCoMInFTSensorFrame).
cross(tcpGravForceVec);
290 tcpGravityCompensation.head<3>() = tcpGravForceVec;
291 tcpGravityCompensation.tail<3>() = tcpGravTorqueVec;
295 tcpGravityCompensation.setZero();
297 return tcpGravityCompensation;
303 filteredForce = (1 -
c.ftFilter) * filteredForce +
c.ftFilter * rawForce;
304 filteredTorque = (1 -
c.ftFilter) * filteredTorque +
c.ftFilter * rawTorque;
306 filteredForceInRoot = sensorOriInRoot * (filteredForce - forceOffset) -
307 tcpGravityCompensation.head<3>() -
c.forceBaseline;
308 filteredTorqueInRoot = sensorOriInRoot * (filteredTorque - torqueOffset) -
309 tcpGravityCompensation.tail<3>() -
c.torqueBaseline;
311 for (
size_t i = 0; i < 3; ++i)
313 if (fabs(filteredForceInRoot(i)) >
c.deadZoneForce)
315 filteredForceInRoot(i) -=
316 (filteredForceInRoot(i) / fabs(filteredForceInRoot(i))) *
c.deadZoneForce;
320 filteredForceInRoot(i) = 0;
323 if (fabs(filteredTorqueInRoot(i)) >
c.deadZoneTorque)
325 filteredTorqueInRoot(i) -=
326 (filteredTorqueInRoot(i) / fabs(filteredTorqueInRoot(i))) *
c.deadZoneTorque;
330 filteredTorqueInRoot(i) = 0;
334 ft.head<3>() = filteredForceInRoot;
335 ft.tail<3>() = filteredTorqueInRoot;
342 return safeGuardForceOffset;
#define ARMARX_RT_LOGF_IMPORTANT(...)
The SensorValueBase class.
std::atomic_bool calibrated
bool isSafe(const FTConfig &c)
Eigen::Vector3f & getSafeGuardForceOffset()
Eigen::Vector6f & getFilteredForceTorque(const FTConfig &data)
bool isForceGuardEnabled()
arondto::FTConfig FTConfig
void enableSafeGuard(bool enableForceGuard, bool enableTorqueGuard)
std::atomic_bool ftWasNotSafe
bool isTorqueGuardEnabled()
Eigen::Vector6f & compensateTCPGravity(const FTConfig &data)
void initialize(const VirtualRobot::RobotNodeSetPtr &rns, const armarx::RobotUnitPtr &robotUnit, const FTConfig &c)
bool calibrate(const FTConfig &c, double deltaT)
void updateStatus(const FTConfig &c, Eigen::Vector6f ¤tFT, double deltaT, bool firstRun)
void resetSafeGuardOffset(const FTConfig &c)
#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...
#define ARMARX_INFO
The normal logging level.
Matrix< float, 6, 1 > Vector6f
This file is part of ArmarX.
IceUtil::Handle< class RobotUnit > RobotUnitPtr
double norm(const Point &a)
Point cross(const Point &x, const Point &y)