CollisionAvoidanceImpedanceController.cpp
Go to the documentation of this file.
1 /**
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @author Jianfeng Gao ( jianfeng dot gao at kit dot edu )
17  * @date 2023
18  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19  * GNU General Public License
20  */
21 
23 
25 
27 {
28  NJointControllerRegistration<NJointTSCollisionAvoidanceImpedanceMPController>
30  "NJointTSCollisionAvoidanceImpedanceMPController");
31 
34  const NJointControllerConfigPtr& config,
35  const VirtualRobot::RobotPtr& robot) :
36  NJointTaskspaceImpedanceController(robotUnit, config, robot),
38  {
39  ARMARX_IMPORTANT << getClassName() + " construction done";
40  }
41 
42  std::string
44  {
45  return "NJointTSCollisionAvoidanceImpedanceMPController";
46  }
47 
48  void
51  const Ice::Current& iceCurrent)
52  {
54  {
55  for (auto& pair : limb)
56  {
57  pair.second->rtFirstRun.store(true);
58  }
59  }
60  }
61 
62  void
64  {
65  std::lock_guard<std::recursive_mutex> lock(mtx_mps);
66  bool rtSafe = additionalTaskUpdateStatus();
67 
68  std::map<std::string, bool> mpRunning;
69  for (auto& _mp : mps)
70  {
71  mpRunning[_mp.second.mp->getMPName()] = _mp.second.mp->isRunning();
72  if (_mp.second.mp->isFinished())
73  {
74  continue;
75  }
76  if (_mp.second.mp->getRole() == "taskspace")
77  {
78  auto& arm = limb.at(_mp.second.mp->getNodeSetName());
79  if (_mp.second.mp->isFirstRun())
80  {
81  _mp.second.mp->validateInitialState(common::mat4ToDVec(arm->rtStatusInNonRT.currentPose));
82  }
83  mp::TSMPInputPtr in = std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
84  in->pose = arm->rtStatusInNonRT.currentPose;
85  in->vel = arm->rtStatusInNonRT.currentTwist;
86  in->deltaT = arm->rtStatusInNonRT.deltaT;
87  }
88  else if (_mp.second.mp->getRole() == "nullspace")
89  {
90  auto& arm = limb.at(_mp.second.mp->getNodeSetName());
91  mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
92  ARMARX_CHECK_EQUAL(arm->rtStatusInNonRT.numJoints,
93  arm->rtStatusInNonRT.jointPos.size());
94  in->angleRadian = arm->rtStatusInNonRT.jointPos;
95  in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
96  in->deltaT = arm->rtStatusInNonRT.deltaT;
97  }
98  else if (_mp.second.mp->getRole() == "hand")
99  {
100  auto& hand = hands->hands.at(_mp.second.mp->getNodeSetName());
101  mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
102  in->angleRadian =
103  hand->bufferRTToNonRT.getUpToDateReadBuffer().jointPosition.value();
104  in->deltaT = hand->bufferRTToNonRT.getReadBuffer().deltaT;
105  }
106  }
107  if (not rtSafe)
108  {
110  return;
111  // Make sure that you do not call additionalTaskSetTarget before return;
112  // since we overwrite the arm->nonRtConfig in additionalTaskUpdateStatus() with user config, which does not
113  // align with the up-to-date mp status. userConfig is only updated to align with MP status everytime a MP
114  // finishes execution. Only then, user can use this controller as if no mp is there.
115  }
116 
117  runMPs(rtSafe);
118 
119  /// set mp target to nonRT config data structure
120  for (auto& _mp : mps)
121  {
122  if (not mpRunning.at(_mp.second.mp->getMPName()))
123  {
124  continue;
125  }
126  for (auto& ftGuard : mpConfig.ftGuard)
127  {
128  if (ftGuard.mpName == _mp.second.mp->getMPName())
129  {
130  bool const forceGuard =
131  (ftGuard.force.has_value() and
132  ftGuard.force.value() >= _mp.second.mp->getCanonicalValue());
133  bool const torqueGuard =
134  (ftGuard.torque.has_value() and
135  ftGuard.torque.value() >= _mp.second.mp->getCanonicalValue());
136 
137  auto& arm = limb.at(_mp.second.mp->getNodeSetName());
138  bool const resetForce =
139  not arm->nonRtConfig.ftConfig.enableSafeGuardForce and forceGuard;
140  bool const resetTorque =
141  not arm->nonRtConfig.ftConfig.enableSafeGuardTorque and torqueGuard;
142  if (resetForce or resetTorque)
143  {
144  ARMARX_INFO << "Triggering force torque safety guard for "
145  << arm->kinematicChainName << " at can value "
146  << _mp.second.mp->getCanonicalValue();
147  }
148 
149  arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
150  arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
151  arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
152  }
153  }
154 
155  if (_mp.second.mp->getRole() == "taskspace")
156  {
157  auto& arm = limb.at(_mp.second.mp->getNodeSetName());
158  mp::TSMPOutputPtr out =
159  std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
160 
161  /// Note that here we only report warning but still set target to RT, we rely on MP phase stop and
162  /// RT safety mechanism to stop or pause the action if needed
163  common::detectAndReportPoseDeviationWarning(arm->rtStatusInNonRT.currentPose,
164  out->pose,
165  "current pose", "TSMP pose",
166  arm->nonRtConfig.safeDistanceMMToGoal,
167  arm->nonRtConfig.safeRotAngleDegreeToGoal,
168  _mp.second.mp->getMPName() + "mp_set_target");
169  arm->nonRtConfig.desiredPose = out->pose;
170  arm->nonRtConfig.desiredTwist = out->vel;
171  }
172  else if (_mp.second.mp->getRole() == "nullspace")
173  {
174  auto& arm = limb.at(_mp.second.mp->getNodeSetName());
175  mp::JSMPOutputPtr out =
176  std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
177  ARMARX_CHECK_EQUAL(arm->rtStatusInNonRT.numJoints, out->angleRadian.size());
178  arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
179  }
180  else if (_mp.second.mp->getRole() == "hand")
181  {
182  mp::JSMPOutputPtr out =
183  std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
184  auto& hand = hands->hands.at(_mp.second.mp->getNodeSetName());
185  mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
186  ARMARX_CHECK_EQUAL(hand->targetNonRT.jointPosition.value().size(),
187  out->angleRadian.size());
188  hand->targetNonRT.jointPosition.value() = out->angleRadian;
189  }
190  if (mpRunning.at(_mp.second.mp->getMPName()) and _mp.second.mp->isFinished())
191  {
192  ARMARX_INFO << "reset buffer for nonRtConfig of " << _mp.second.mp->getMPName();
193  for (auto& pair : limb)
194  {
195  auto& arm = pair.second;
196  arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
197  }
198  for (auto& pair : limb)
199  {
200  userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;
201  }
202  if (hands)
203  {
204  hands->reinitBuffer(userConfig.hands);
205  }
206  }
207  }
209  }
210 } // namespace armarx::control::njoint_mp_controller::task_space
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController
Brief description of class NJointTaskspaceImpedanceController.
Definition: ImpedanceController.h:51
armarx::control::njoint_mp_controller::task_space::registrationControllerNJointTSCollisionAvoidanceImpedanceMPController
NJointControllerRegistration< NJointTSCollisionAvoidanceImpedanceMPController > registrationControllerNJointTSCollisionAvoidanceImpedanceMPController("NJointTSCollisionAvoidanceImpedanceMPController")
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::handleRTNotSafeInNonRT
void handleRTNotSafeInNonRT()
Definition: ImpedanceController.cpp:210
armarx::control::common::mp::JSMPInputPtr
std::shared_ptr< JSMPInput > JSMPInputPtr
Definition: JSMP.h:47
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::hands
core::HandControlPtr hands
Definition: ImpedanceController.h:164
armarx::control::common::detectAndReportPoseDeviationWarning
bool detectAndReportPoseDeviationWarning(const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2, const std::string &namePose1, const std::string &namePose2, float positionThrMM, float angleThrDeg, const std::string &who)
Definition: utils.cpp:600
armarx::control::njoint_mp_controller::task_space::NJointTSCollisionAvoidanceImpedanceMPController::getClassName
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override
Definition: CollisionAvoidanceImpedanceController.cpp:43
armarx::control::common::mp::MPPool::runMPs
void runMPs(const bool rtSafe)
Definition: MPPool.cpp:83
armarx::control::njoint_mp_controller::task_space::NJointTSCollisionAvoidanceImpedanceMPController::NJointTSCollisionAvoidanceImpedanceMPController
NJointTSCollisionAvoidanceImpedanceMPController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition: CollisionAvoidanceImpedanceController.cpp:33
armarx::control::common::mp::JSMPOutputPtr
std::shared_ptr< JSMPOutput > JSMPOutputPtr
Definition: JSMP.h:48
armarx::control::common::mp::MPPool::resetMPs
bool resetMPs(const ::armarx::aron::data::dto::DictPtr &dto, const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap)
Definition: MPPool.cpp:500
CollisionAvoidanceImpedanceController.h
armarx::control::common::mp::TSMPOutputPtr
std::shared_ptr< TSMPOutput > TSMPOutputPtr
Definition: TSMP.h:47
armarx::control::common::mp::MPPool::mtx_mps
std::recursive_mutex mtx_mps
Definition: MPPool.h:128
armarx::control::njoint_controller::task_space::NJointTaskspaceCollisionAvoidanceImpedanceController
Brief description of class NJointTaskspaceCollisionAvoidanceImpedanceController.
Definition: CollisionAvoidanceImpedanceController.h:58
armarx::control::njoint_mp_controller::task_space::NJointTSCollisionAvoidanceImpedanceMPController::additionalTask
void additionalTask() override
Definition: CollisionAvoidanceImpedanceController.cpp:63
utils.h
armarx::control::njoint_mp_controller::task_space
This file is part of ArmarX.
Definition: AdmittanceController.cpp:26
armarx::control::njoint_mp_controller::task_space::NJointTSCollisionAvoidanceImpedanceMPController::updateMPConfig
void updateMPConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition: CollisionAvoidanceImpedanceController.cpp:49
armarx::control::common::MPType::hand
@ hand
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::controllableNodeSets
std::map< std::string, VirtualRobot::RobotNodeSetPtr > controllableNodeSets
Definition: ImpedanceController.h:165
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::additionalTaskSetTarget
void additionalTaskSetTarget()
Definition: ImpedanceController.cpp:197
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::limb
std::map< std::string, ArmPtr > limb
Definition: ImpedanceController.h:160
armarx::control::common::mat4ToDVec
mplib::core::DVec mat4ToDVec(const Eigen::Matrix4f &mat)
convert Eigen:Matrix4f to 7D double vector.
Definition: utils.cpp:240
armarx::control::common::mp::MPPool::mps
std::map< std::string, MPInputOutput > mps
Definition: MPPool.h:127
armarx::control::common::mp::TSMPInputPtr
std::shared_ptr< TSMPInput > TSMPInputPtr
Definition: TSMP.h:46
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::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::additionalTaskUpdateStatus
bool additionalTaskUpdateStatus()
Definition: ImpedanceController.cpp:178
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::userConfig
ConfigDict userConfig
Definition: ImpedanceController.h:163
armarx::control::njoint_controller::task_space::NJointTaskspaceImpedanceController::robotUnit
RobotUnitPtr robotUnit
Definition: ImpedanceController.h:162
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::control::common::mp::MPPool::mpConfig
MPListConfig mpConfig
this variable is only needed when constructing the MP instances, therefore you don't need to use trip...
Definition: MPPool.h:134