CollisionAvoidanceCore.cpp
Go to the documentation of this file.
2 
4 {
5 
7  const Config& cfg) :
8  rtRobot(rtRobotPtr)
9  {
10  ARMARX_DEBUG << "creating collison avoidance base";
11  ARMARX_CHECK_EXPRESSION(rtRobot);
12 
13  rtCfg = cfg;
14  validateConfigData(rtCfg);
15  userCfg = rtCfg;
17 
18  // rtCfg.maxCollisionPairs;
19  // rtCfg.actuatedRobotNodeSetName;
20  // rtCfg.primitiveModelID;
21  std::vector<std::string> tcpNodeNames;
22  for (auto& pair : rtCfg.ctrlCfg)
23  {
24  const auto nodeset = rtRobot->getRobotNodeSet(pair.first);
25  std::string tcpName = nodeset->getTCP()->getName();
26  tcpNodeNames.push_back(tcpName);
27  if (pair.second.distanceThreshold > preFilterDistance)
28  {
29  preFilterDistance = pair.second.distanceThreshold;
30  }
31  }
32 
33  /// add actuated robot joints
34  /// use a robot nodeset with all actuated joints, arms including head and torso joints, which change
35  /// the position of the robot body parts for correct collision checking
37  rtRobot->getRobotNodeSet(rtCfg.actuatedRobotNodeSetName)->getNodeNames();
38 
39  /// initialize simox control robot for self-collision checking
40  const bool reduceModel = true; // for performance and ignoreCollision detection
42  std::make_shared<SimoxRobot>(rtRobot, actuatedJointNames, tcpNodeNames, reduceModel);
44 
45  // std::vector<std::string> primitiveModelIDs{rtCfg.primitiveModelID};
46 
47  collisionRobotPtr = std::make_unique<CollisionRobot>(
48  *simoxReducedRobotPtr, std::string(), true, rtCfg.primitiveModelParts);
50 
51  collisionPairs = std::make_shared<DistanceResults>(rtCfg.maxCollisionPairs);
52  collisionPairs->reserve(rtCfg.maxCollisionPairs);
53 
54  /// create not reduced simox control robot for inertia calculation
56  std::make_shared<SimoxRobot>(rtRobot, actuatedJointNames, tcpNodeNames, false);
58 
59  // initialize vector to store the current joint values of all actuated joints to update
60  // the simox robots with the most recent values, so the simox control robots display the
61  // current joint configuration of the real world model
63  qposActuatedJoints.setZero();
64 
65  size_t jointIdx = 0;
66  for (const auto& nodeName : actuatedJointNames)
67  {
68  auto node = rtRobot->getRobotNode(nodeName);
69  if (node->isTranslationalJoint())
70  {
71  // convert value from mm to m for simox control robot
72  // all translational values of the simox control robots are in meter
73  ARMARX_INFO << "-- adding translation joint " << nodeName
74  << " with scaling 0.001 from mm to meter";
75  translationJointIndex.push_back(jointIdx);
76  ++jointIdx;
77  }
78  }
79 
80  for (auto& pair : rtCfg.ctrlCfg)
81  {
82  collLimb.emplace(pair.first,
83  std::make_shared<CollisionAvoidanceArmData>(rtRobot,
84  pair.first,
88  rtCfg));
89  }
90  }
91 
93  {
94  ARMARX_IMPORTANT << "destruction of CollisionAvoidanceBase";
95  }
96 
98  VirtualRobot::RobotPtr rtRobot,
99  const std::string& robotNodeSetName,
100  SimoxRobotPtr simoxReducedRobot,
101  SimoxRobotPtr simoxControlRobot,
102  DistanceResultsPtr collisionPairs,
103  Config& c) :
104  nodeSetName(robotNodeSetName),
105  rtRNS(rtRobot->getRobotNodeSet(robotNodeSetName)),
106  // controller(law::CollisionAvoidanceController(rtRNS, simoxReducedRobotPtr)),
107  controller(rtRNS),
108  collisionPairsPtr(collisionPairs),
109  pointsOnArm(std::make_shared<std::vector<int>>(c.maxCollisionPairs, -1)),
110  pointsOnArmIndex(0),
111  simoxReducedRobotPtr(simoxReducedRobot)
112  {
115  ARMARX_CHECK_GREATER(c.maxCollisionPairs, 0);
117 
118  tcpName = rtRNS->getTCP()->getName();
119  jointNames = rtRNS->getNodeNames();
120 
121  controller.initialize(simoxReducedRobotPtr);
122 
123  ARMARX_CHECK_GREATER(controller.numOfJoints, 0);
124  rts.reset(
125  c.ctrlCfg.at(robotNodeSetName), controller.numOfJoints, c.maxCollisionPairs, rtRNS);
126  inertiaPtr = std::make_shared<simox::control::geodesics::metric::Inertia>(
127  *simoxControlRobot, robotNodeSetName);
128 
130 
132  }
133 
134  void
136  {
137  std::fill(pointsOnArm->begin(), pointsOnArm->end(), -1);
138  pointsOnArmIndex = 0;
139  rts.reset(
140  c.ctrlCfg.at(rtRNS->getName()), controller.numOfJoints, c.maxCollisionPairs, rtRNS);
141  }
142 
143  void
145  {
146  for (auto& pair : collLimb)
147  {
148  pair.second->rts.rtPreActivate();
149  }
150  }
151 
152  void
154  {
155  for (auto& pair : collLimb)
156  {
157  pair.second->reset(rtCfg);
158  }
159  }
160 
161  void
163  {
164  /// Running in rt thread.
166  validateConfigData(rtCfg);
167  }
168 
169  void
171  {
172  /// ----------------- update joint values for simox Robots ---------------------------------
173  qposActuatedJoints = rtRobot->getRobotNodeSet(rtCfg.actuatedRobotNodeSetName)
174  ->getJointValuesEigen()
175  .cast<double>();
176  for (auto& i : translationJointIndex)
177  {
178  // convert value from mm to m for simox control robot
179  // all translational values of the simox control robots are in meter
180  qposActuatedJoints(i) *= 0.001;
181  }
182 
183  /// ----------------- update Simox robots --------------------------------------------------
184  ///
185  /// a VectorXd is needed with nodeSet size (size of actuated joints in order of vector,
186  /// which has been used for initialization in init
187  ///
188  /// It is very important that the simox robots map the current joint configuration of the
189  /// real-world robot
192 
193  /// ----------------- calculation of robot collision pairs ---------------------------------
194  double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
195  /// _______TODO_______ the following line is commented out, to avoid allocation of new memory
196  collisionPairs->clear(); // empty collision pairs before assigning new ones
197 
198  /// !!! individualColObjects has to be set to true (second flag, that is passed) !!!
199  /// if not set to true, the body and the arms become attractive, be aware
200  /// _______TODO_______ consider passing the pre-allocated results to the simox lib.
201  DistanceResults results =
202  collisionRobotPtr->computeMinimumSelfCollisionDistance(true, true);
203 
204  collisionPairs->insert(collisionPairs->end(), results.begin(), results.end());
205 
206  double collisionPairTime = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
207 
208  for (auto& pair : collLimb)
209  {
210  /// reset temporary pointsOnArmIndex
211  pair.second->pointsOnArmIndex = 0;
212  pair.second->rts.collisionPairTime = collisionPairTime;
213  pair.second->rts.collisionPairsNum = collisionPairs->size();
214  }
215 
216 
217  /// checks whether the point is located on the arm and fills the pointsOnArm vector with the
218  /// corresponding indices
219  /// the entries in the pointsOnArm vector store the indices of the collision pairs that are
220  /// on the arm and which must be taken into account in the control law
221 
222  timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
223  for (size_t i = 0; i < collisionPairs->size(); ++i)
224  {
225  ARMARX_CHECK(collisionPairs->at(i).hasPoints());
226 
227  /// prefilter contact pairs based on distance
228  if (static_cast<float>(collisionPairs->at(i).minDistance) <= preFilterDistance)
229  {
230 
231  /// set index in integer vector of contact point on arm below preFilterDistance
232  for (auto& pair : collLimb)
233  {
234 
235  auto& arm = pair.second;
236  if (arm->pointsOnArmIndex >= rtCfg.maxCollisionPairs)
237  continue;
238  if (std::find(arm->jointNames.begin(),
239  arm->jointNames.end(),
240  collisionPairs->at(i).node1) != arm->jointNames.end() or
241  arm->tcpName == collisionPairs->at(i).node1)
242  {
243  /// _______TODO_______ what if there are more collision pairs than 100? added above check with maxCollisionPairs
244  // note: if node1 and node2 are on arm, this is handeled in law
245  // here it is only important, whether the coll pair is regarded for the arm
246  arm->pointsOnArm->at(arm->pointsOnArmIndex) = i;
247  arm->pointsOnArmIndex++;
248  }
249  else if (std::find(arm->jointNames.begin(),
250  arm->jointNames.end(),
251  collisionPairs->at(i).node2) != arm->jointNames.end() or
252  arm->tcpName == collisionPairs->at(i).node2)
253  {
254  arm->pointsOnArm->at(arm->pointsOnArmIndex) = i;
255  arm->pointsOnArmIndex++;
256  }
257  }
258  }
259  }
260  // ARMARX_INFO << "detected collision pairs: " << collisionPairs->size();
261  double preFilterTime = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
262 
263  if (preFilterTime > 100 or collisionPairTime > 100)
264  {
265  ARMARX_RT_LOGF_WARN("---- rt too slow: "
266  "preFilterTime: %.2f\n"
267  "collisionPairTime: %.2f\n",
268  preFilterTime, // 3-4 us
269  collisionPairTime)
270  .deactivateSpam(1.0f); // 28-31 us
271  }
272  }
273 
274  void
275  CollisionAvoidanceBase::rtLimbControllerRun(const std::string& robotNodeSetName,
276  Eigen::VectorXf& qpos,
277  Eigen::VectorXf& qvelFiltered,
278  float torqueLimit,
279  Eigen::VectorXf& impedanceJointTorque)
280  {
281  auto& arm = collLimb.at(robotNodeSetName);
282  /// set all invalid indeces of this rt cycle to -1
283  for (size_t i = arm->pointsOnArmIndex; i < arm->pointsOnArm->size(); ++i)
284  {
285  arm->pointsOnArm->at(i) = -1;
286  }
287  // arm->rts.preFilterTime = preFilterTime;
288  // arm->rts.activeCollPairsNum = arm->pointsOnArmIndex;
289 
290  ARMARX_CHECK_EQUAL(arm->rts.impedanceJointTorque.size(), impedanceJointTorque.size());
291  arm->rts.impedanceJointTorque = impedanceJointTorque;
292  arm->controller.run(rtCfg.ctrlCfg.at(robotNodeSetName),
293  arm->rts,
294  arm->collisionPairsPtr,
295  arm->pointsOnArm,
296  arm->pointsOnArmIndex,
297  arm->inertiaPtr,
298  arm->jointNames,
299  qpos,
300  qvelFiltered,
301  torqueLimit);
302  arm->bufferRTtoPublish.getWriteBuffer() = arm->rts;
303  arm->bufferRTtoPublish.commitWrite();
304  }
305 
306  void
308  {
309  ARMARX_CHECK_NONNEGATIVE(cfg.maxCollisionPairs);
310  ARMARX_CHECK_NOT_EMPTY(cfg.primitiveModelParts);
311  ARMARX_CHECK_NOT_EMPTY(cfg.actuatedRobotNodeSetName);
312  for (auto& pair : cfg.ctrlCfg)
313  {
315  }
316  }
317 
318  void
320  {
321  userCfg = cfg;
325  }
326 
327 
328 } // namespace armarx::control::njoint_controller::core
armarx::control::njoint_controller::core::CollisionAvoidanceBase::setUserCfg
void setUserCfg(const Config &cfg)
Definition: CollisionAvoidanceCore.cpp:319
armarx::control::njoint_controller::core::CollisionAvoidanceBase::~CollisionAvoidanceBase
~CollisionAvoidanceBase()
Definition: CollisionAvoidanceCore.cpp:92
ARMARX_CHECK_NONNEGATIVE
#define ARMARX_CHECK_NONNEGATIVE(number)
Check whether number is nonnegative (>= 0). If it is not, throw an ExpressionException with the expre...
Definition: ExpressionException.h:152
armarx::control::njoint_controller::core::CollisionAvoidanceBase::collisionRobotPtr
CollisionRobotPtr collisionRobotPtr
Definition: CollisionAvoidanceCore.h:126
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceBase
CollisionAvoidanceBase(const VirtualRobot::RobotPtr &rtRobot, const Config &cfg)
Definition: CollisionAvoidanceCore.cpp:6
armarx::TripleBuffer::getWriteBuffer
T & getWriteBuffer()
Definition: TripleBuffer.h:90
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::inertiaPtr
InertiaPtr inertiaPtr
self-collision avoidance
Definition: CollisionAvoidanceCore.h:86
armarx::control::common::control_law::collision::validateConfigData
void validateConfigData(arondto::CollisionAvoidanceConfig &cfg)
Definition: CollisionAvoidance.cpp:1616
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtPreActivate
void rtPreActivate()
Definition: CollisionAvoidanceCore.cpp:144
armarx::control::njoint_controller::core::CollisionAvoidanceBase::userCfg
Config userCfg
Definition: CollisionAvoidanceCore.h:119
armarx::TripleBuffer::commitWrite
void commitWrite()
Definition: TripleBuffer.h:146
armarx::control::njoint_controller::core::CollisionAvoidanceBase::SimoxRobotPtr
std::shared_ptr< SimoxRobot > SimoxRobotPtr
Definition: CollisionAvoidanceCore.h:57
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::tcpName
std::string tcpName
Definition: CollisionAvoidanceCore.h:77
armarx::control::njoint_controller::core::CollisionAvoidanceBase::Config
::armarx::control::common::control_law::arondto::CollisionAvoidanceConfigDict Config
Definition: CollisionAvoidanceCore.h:65
ARMARX_CHECK_GREATER
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
Definition: ExpressionException.h:116
armarx::control::njoint_controller::core::CollisionAvoidanceBase::actuatedJointNames
std::vector< std::string > actuatedJointNames
Definition: CollisionAvoidanceCore.h:131
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::jointNames
std::vector< std::string > jointNames
Definition: CollisionAvoidanceCore.h:78
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::rts
RtStatus rts
Definition: CollisionAvoidanceCore.h:82
ARMARX_CHECK_NOT_EMPTY
#define ARMARX_CHECK_NOT_EMPTY(c)
Definition: ExpressionException.h:224
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtLimbControllerRun
void rtLimbControllerRun(const std::string &robotNodeSetName, Eigen::VectorXf &qpos, Eigen::VectorXf &qvelFiltered, float torqueLimit, Eigen::VectorXf &impedanceJointTorque)
Definition: CollisionAvoidanceCore.cpp:275
armarx::control::njoint_controller::core
This file is part of ArmarX.
Definition: CollisionAvoidanceCore.cpp:3
CollisionAvoidanceCore.h
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::control::njoint_controller::core::CollisionAvoidanceBase::bufferCfgUserToRT
armarx::TripleBuffer< Config > bufferCfgUserToRT
Definition: CollisionAvoidanceCore.h:120
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::CollisionAvoidanceArmData
CollisionAvoidanceArmData(VirtualRobot::RobotPtr rtRobot, const std::string &robotNodeSetName, SimoxRobotPtr simoxReducedRobot, SimoxRobotPtr simoxControlRobot, DistanceResultsPtr collisionPairs, Config &c)
Definition: CollisionAvoidanceCore.cpp:97
armarx::control::njoint_controller::core::CollisionAvoidanceBase::DistanceResults
std::vector<::simox::control::environment::DistanceResult > DistanceResults
Definition: CollisionAvoidanceCore.h:58
controller
Definition: AddOperation.h:39
armarx::control::njoint_controller::core::CollisionAvoidanceBase::qposActuatedJoints
Eigen::VectorXd qposActuatedJoints
TODO, rename to actuatedJointNames.
Definition: CollisionAvoidanceCore.h:132
armarx::control::njoint_controller::core::CollisionAvoidanceBase::translationJointIndex
std::vector< int > translationJointIndex
Definition: CollisionAvoidanceCore.h:133
armarx::control::njoint_controller::core::CollisionAvoidanceBase::updateRtConfigFromUser
void updateRtConfigFromUser()
Definition: CollisionAvoidanceCore.cpp:162
armarx::control::njoint_controller::core::CollisionAvoidanceBase::simoxReducedRobotPtr
SimoxRobotPtr simoxReducedRobotPtr
Definition: CollisionAvoidanceCore.h:128
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtPostDeactivate
void rtPostDeactivate()
Definition: CollisionAvoidanceCore.cpp:153
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::collisionPairsPtr
DistanceResultsPtr collisionPairsPtr
Definition: CollisionAvoidanceCore.h:87
armarx::control::njoint_controller::core::CollisionAvoidanceBase::DistanceResultsPtr
std::shared_ptr< DistanceResults > DistanceResultsPtr
Definition: CollisionAvoidanceCore.h:59
armarx::make_shared
auto make_shared(Args &&...args)
Definition: ManagedIceObject.h:90
armarx::control::njoint_controller::core::CollisionAvoidanceBase::simoxControlRobotPtr
SimoxRobotPtr simoxControlRobotPtr
Definition: CollisionAvoidanceCore.h:127
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::bufferRTtoPublish
armarx::TripleBuffer< RtStatus > bufferRTtoPublish
Definition: CollisionAvoidanceCore.h:83
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::control::njoint_controller::core::CollisionAvoidanceBase::collLimb
std::map< std::string, CollArmPtr > collLimb
Definition: CollisionAvoidanceCore.h:118
std
Definition: Application.h:66
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::reset
void reset(Config &c)
Definition: CollisionAvoidanceCore.cpp:135
armarx::control::njoint_controller::core::CollisionAvoidanceBase::collisionPairs
DistanceResultsPtr collisionPairs
Definition: CollisionAvoidanceCore.h:129
armarx::TripleBuffer::getUpToDateReadBuffer
const T & getUpToDateReadBuffer() const
Definition: TripleBuffer.h:108
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:345
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::rtRNS
VirtualRobot::RobotNodeSetPtr rtRNS
!!!!!!! Note that, all the data below should only be accessed in rt thread !!!!!!!
Definition: CollisionAvoidanceCore.h:76
armarx::control::njoint_controller::core::CollisionAvoidanceBase::validateConfigData
void validateConfigData(Config &cfg)
Definition: CollisionAvoidanceCore.cpp:307
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtCollisionChecking
void rtCollisionChecking()
Definition: CollisionAvoidanceCore.cpp:170
armarx::control::njoint_controller::core::CollisionAvoidanceBase::CollisionAvoidanceArmData::simoxReducedRobotPtr
SimoxRobotPtr simoxReducedRobotPtr
Definition: CollisionAvoidanceCore.h:92
armarx::TripleBuffer::reinitAllBuffers
std::enable_if< std::is_copy_constructible< U >::value >::type reinitAllBuffers(const T &init)
Definition: TripleBuffer.h:153
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18