CollisionAvoidanceCore.cpp
Go to the documentation of this file.
2 
3 
4 #include <VirtualRobot/Nodes/RobotNode.h>
5 #include <VirtualRobot/Robot.h>
6 #include <VirtualRobot/RobotNodeSet.h>
7 
8 #include <simox/control/environment/CollisionRobot.h>
9 #include <simox/control/impl/simox/robot/Robot.h>
10 
13 
15 {
16 
18  const Config& cfg) :
19  rtRobot(rtRobot)
20  {
21  ARMARX_CHECK_EXPRESSION(rtRobot);
22 
23  rtCfg = cfg;
24  validateConfigData(rtCfg);
25  userCfg = rtCfg;
27 
28  // Collect tcp node names
29  std::vector<std::string> tcpNodeNames;
30  for (const auto& pair : rtCfg.ctrlCfg)
31  {
32  const auto nodeset = rtRobot->getRobotNodeSet(pair.first);
33  const std::string tcpName = nodeset->getTCP()->getName();
34  tcpNodeNames.push_back(tcpName);
35  if (pair.second.distanceThreshold > preFilterDistance)
36  {
37  preFilterDistance = pair.second.distanceThreshold;
38  }
39  }
40 
41  /// add actuated robot joints
42  /// use a robot nodeset with all actuated joints, arms including head and torso joints, which change
43  /// the position of the robot body parts for correct collision checking
45  rtRobot->getRobotNodeSet(rtCfg.actuatedRobotNodeSetName)->getNodeNames();
46 
47  /// initialize simox control robot for self-collision checking
48  scRobot = std::make_unique<simox::control::simox::robot::Robot>(
49  rtRobot, actuatedJointNames, tcpNodeNames, reduceModel);
50  scRobot->setGlobalPose(Eigen::Isometry3d::Identity());
51 
52  ARMARX_INFO << "Creating robot model for collision computation using default primitive models and models with id " << rtCfg.primitiveModelParts;
53 
54  collisionRobot = std::make_unique<simox::control::environment::CollisionRobot<hpp::fcl::OBBRSS>>(
55  *scRobot,
56  simox::control::environment::CollisionRobotParams {
57  .loadDefaultPrimitiveModel = true,
58  .primitiveModelIDs = rtCfg.primitiveModelParts,
59  .sortNodes = true});
60 
61  // initialize vector to store the current joint values of all actuated joints to update
62  // the simox robots with the most recent values, so the simox control robots display the
63  // current joint configuration of the real world model
65  qposActuatedJoints.setZero();
66 
67  size_t jointIdx = 0;
68  for (const auto& nodeName : actuatedJointNames)
69  {
70  const auto node = rtRobot->getRobotNode(nodeName);
71  if (node->isTranslationalJoint())
72  {
73  // convert value from mm to m for simox control robot
74  // all translational values of the simox control robots are in meter
75  translationJointIndex.push_back(jointIdx);
76  }
77  jointIdx++;
78  }
79 
80  for (const auto& pair : rtCfg.ctrlCfg)
81  {
82  collLimb.try_emplace(pair.first, rtRobot, pair.first, *scRobot, collisionPairs, rtCfg);
83  }
84 
85  // Store all indices
86  ARMARX_INFO << "Creating index to node mapping for collision robot:";
87  std::unordered_set<unsigned int> consideredIndices;
88  for (auto& [name, data] : collLimb)
89  {
90  collisionRobot->getIndices(data.controller.getNodeSet(), data.collisionRobotIndices);
91  for (const auto& [index, node] : data.collisionRobotIndices)
92  {
93  ARMARX_INFO << "Mapping index " << index << " to node " << node->getName()
94  << " for limb " << name;
95  consideredIndices.insert(index);
96  }
97  }
98 
99  ARMARX_INFO << "Initial computation of all self collision pairs";
100 
101  selfColAvoidanceArgs = simox::control::environment::CompDistArgs{
102  .updatePose = false,
103  .nearestPoints = true,
104  .individualColObjects = true,
105  .allowIndices = consideredIndices};
106 
107  // Compute number of collision pairs
108  // This will not change if no objects are attached and the args are not changed
109  collisionRobot->update(false); // update pose
110  const DistanceResults distanceResults =
111  collisionRobot->computeMinimumSelfCollisionDistance(selfColAvoidanceArgs);
112  const int nElements = distanceResults.size();
113 
114  for (const auto& distanceResult : distanceResults)
115  {
116  ARMARX_INFO
117  << "Considering distance between "
118  << collisionRobot->getNodes().at(distanceResult.node1).getName() << " and "
119  << collisionRobot->getNodes().at(distanceResult.node2).getName()
120  << ". Initial distance: " << distanceResult.minDistance << "m";
121  }
122 
123  ARMARX_INFO << "Reserving space for " << nElements << " collision pairs";
124  ARMARX_CHECK_EXPRESSION(nElements < rtCfg.maxCollisionPairs);
125  collisionPairs.reserve(nElements);
126  }
127 
129  {
130  ARMARX_IMPORTANT << "destruction of CollisionAvoidanceBase";
131  }
132 
134  const VirtualRobot::RobotPtr& rtRobot,
135  const std::string& robotNodeSetName,
136  const SCRobot& scRobot,
137  const DistanceResults& collisionPairs,
138  const Config& c) :
139  nodeSetName(robotNodeSetName),
140  rtRNS(rtRobot->getRobotNodeSet(robotNodeSetName)),
141  controller(scRobot.getSubNodeSet(robotNodeSetName)),
142  collisionPairs(collisionPairs)
143  {
145  ARMARX_CHECK_GREATER(c.maxCollisionPairs, 0);
146 
147  reset(c);
148 
149  dynamicsModel = scRobot.createDynamicsModel(robotNodeSetName);
150 
152  }
153 
154  void
156  {
157  rts.reset(
158  c.ctrlCfg.at(rtRNS->getName()), controller.numNodes(), c.maxCollisionPairs, rtRNS);
159  }
160 
161  void
163  {
164  for (auto& pair : collLimb)
165  {
166  pair.second.rts.rtPreActivate();
167  }
168  }
169 
170  void
172  {
173  for (auto& pair : collLimb)
174  {
175  pair.second.reset(rtCfg);
176  }
177  }
178 
179  void
181  {
182  /// Running in rt thread.
184  validateConfigData(rtCfg);
185  }
186 
187  void
189  {
190  /// ----------------- update joint values for simox Robots ---------------------------------
191  qposActuatedJoints = rtRobot->getRobotNodeSet(rtCfg.actuatedRobotNodeSetName)
192  ->getJointValuesEigen()
193  .cast<double>();
194 
195  // convert value from mm to m for simox control robot
196  // all translational values of the simox control robots are in meter
197  for (unsigned int i : translationJointIndex)
198  {
199  qposActuatedJoints(i) *= 0.001;
200  }
201 
202  /// ----------------- update Simox robots --------------------------------------------------
203  ///
204  /// a VectorXd is needed with nodeSet size (size of actuated joints in order of vector,
205  /// which has been used for initialization in init
206  ///
207  /// It is very important that the simox robots map the current joint configuration of the
208  /// real-world robot
209  scRobot->setConfig(qposActuatedJoints);
210 
211  /// ----------------- calculation of robot collision pairs ---------------------------------
212  const auto time = IceUtil::Time::now();
213  collisionRobot->update(false); // update pose
214  collisionRobot->computeMinimumSelfCollisionDistance(collisionPairs, selfColAvoidanceArgs);
215  const double collisionPairTime = (IceUtil::Time::now() - time).toMicroSecondsDouble();
216 
217  for (auto& pair : collLimb)
218  {
219  pair.second.rts.collisionPairTime = collisionPairTime;
220  pair.second.rts.collisionPairsNum = collisionPairs.size();
221  }
222  }
223 
224  void
225  CollisionAvoidanceBase::rtLimbControllerRun(const std::string& robotNodeSetName,
226  const Eigen::VectorXf& qpos,
227  const Eigen::VectorXf& qvelFiltered,
228  float torqueLimit,
229  const Eigen::VectorXf& impedanceJointTorque)
230  {
231  auto& arm = collLimb.at(robotNodeSetName);
232 
233  ARMARX_CHECK_EQUAL(arm.rts.impedanceJointTorque.size(), impedanceJointTorque.size());
234  arm.rts.impedanceJointTorque = impedanceJointTorque;
235  arm.controller.run(rtCfg.ctrlCfg.at(robotNodeSetName),
236  arm.rts,
237  arm.collisionPairs,
238  arm.collisionRobotIndices,
239  *arm.dynamicsModel,
240  qpos,
241  qvelFiltered,
242  torqueLimit);
243  arm.bufferRTtoPublish.getWriteBuffer() = arm.rts;
244  arm.bufferRTtoPublish.commitWrite();
245  }
246 
247  void
249  {
250  ARMARX_CHECK_NONNEGATIVE(cfg.maxCollisionPairs);
251  ARMARX_CHECK_NOT_EMPTY(cfg.primitiveModelParts);
252  ARMARX_CHECK_NOT_EMPTY(cfg.actuatedRobotNodeSetName);
253  for (auto& pair : cfg.ctrlCfg)
254  {
256  }
257  }
258 
259  void
261  {
262  userCfg = cfg;
266  }
267 
268 } // namespace armarx::control::njoint_controller::core
armarx::control::njoint_controller::core::CollisionAvoidanceBase::translationJointIndex
std::vector< unsigned int > translationJointIndex
Definition: CollisionAvoidanceCore.h:121
armarx::control::njoint_controller::core::CollisionAvoidanceBase::setUserCfg
void setUserCfg(const Config &cfg)
Definition: CollisionAvoidanceCore.cpp:260
armarx::control::njoint_controller::core::CollisionAvoidanceBase::~CollisionAvoidanceBase
~CollisionAvoidanceBase()
Definition: CollisionAvoidanceCore.cpp:128
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::CollisionAvoidanceBase
CollisionAvoidanceBase(const VirtualRobot::RobotPtr &rtRobot, const Config &cfg)
Definition: CollisionAvoidanceCore.cpp:17
armarx::TripleBuffer::getWriteBuffer
T & getWriteBuffer()
Definition: TripleBuffer.h:92
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
armarx::control::njoint_controller::core::CollisionAvoidanceBase::collisionPairs
DistanceResults collisionPairs
Definition: CollisionAvoidanceCore.h:117
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtPreActivate
void rtPreActivate()
Definition: CollisionAvoidanceCore.cpp:162
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::control::njoint_controller::core::CollisionAvoidanceBase::userCfg
Config userCfg
Definition: CollisionAvoidanceCore.h:108
armarx::TripleBuffer::commitWrite
void commitWrite()
Definition: TripleBuffer.h:163
armarx::control::njoint_controller::core::CollisionAvoidanceBase::NodeSetData::NodeSetData
NodeSetData(const VirtualRobot::RobotPtr &rtRobot, const std::string &robotNodeSetName, const SCRobot &scRobot, const DistanceResults &collisionPairs, const Config &c)
Definition: CollisionAvoidanceCore.cpp:133
armarx::control::common::control_law::collision::validateConfigData
void validateConfigData(const arondto::CollisionAvoidanceConfig &cfg)
Definition: CollisionAvoidance.cpp:979
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
trace.h
armarx::control::njoint_controller::core::CollisionAvoidanceBase::actuatedJointNames
std::vector< std::string > actuatedJointNames
Definition: CollisionAvoidanceCore.h:119
armarx::control::njoint_controller::core::CollisionAvoidanceBase::scRobot
std::unique_ptr< SCRobot > scRobot
Definition: CollisionAvoidanceCore.h:116
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
ARMARX_CHECK_NOT_EMPTY
#define ARMARX_CHECK_NOT_EMPTY(c)
Definition: ExpressionException.h:224
armarx::control::njoint_controller::core
This file is part of ArmarX.
Definition: CollisionAvoidanceCore.cpp:14
armarx::control::njoint_controller::core::CollisionAvoidanceBase::NodeSetData::bufferRTtoPublish
armarx::TripleBuffer< RtStatus > bufferRTtoPublish
Definition: CollisionAvoidanceCore.h:78
CollisionAvoidanceCore.h
armarx::control::njoint_controller::core::CollisionAvoidanceBase::collisionRobot
std::unique_ptr< CollisionRobot > collisionRobot
Definition: CollisionAvoidanceCore.h:115
armarx::control::njoint_controller::core::CollisionAvoidanceBase::bufferCfgUserToRT
armarx::TripleBuffer< Config > bufferCfgUserToRT
Definition: CollisionAvoidanceCore.h:109
armarx::control::njoint_controller::core::CollisionAvoidanceBase::DistanceResults
law::CollisionAvoidanceController::DistanceResults DistanceResults
Definition: CollisionAvoidanceCore.h:59
armarx::control::njoint_controller::core::CollisionAvoidanceBase::SCRobot
law::CollisionAvoidanceController::SCRobot SCRobot
Definition: CollisionAvoidanceCore.h:58
armarx::control::njoint_controller::core::CollisionAvoidanceBase::NodeSetData::rts
RtStatus rts
Definition: CollisionAvoidanceCore.h:77
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
controller
Definition: AddOperation.h:39
armarx::control::njoint_controller::core::CollisionAvoidanceBase::qposActuatedJoints
Eigen::VectorXd qposActuatedJoints
TODO, rename to actuatedJointNames.
Definition: CollisionAvoidanceCore.h:120
armarx::control::njoint_controller::core::CollisionAvoidanceBase::NodeSetData::dynamicsModel
std::unique_ptr< DynamicsModel > dynamicsModel
self-collision avoidance
Definition: CollisionAvoidanceCore.h:81
armarx::control::njoint_controller::core::CollisionAvoidanceBase::updateRtConfigFromUser
void updateRtConfigFromUser()
Definition: CollisionAvoidanceCore.cpp:180
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtPostDeactivate
void rtPostDeactivate()
Definition: CollisionAvoidanceCore.cpp:171
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::control::njoint_controller::core::CollisionAvoidanceBase::validateConfigData
void validateConfigData(const Config &cfg)
Definition: CollisionAvoidanceCore.cpp:248
armarx::control::njoint_controller::core::CollisionAvoidanceBase::NodeSetData::reset
void reset(const Config &c)
Definition: CollisionAvoidanceCore.cpp:155
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:181
armarx::control::njoint_controller::core::CollisionAvoidanceBase::collLimb
std::map< std::string, NodeSetData > collLimb
Definition: CollisionAvoidanceCore.h:107
Logging.h
armarx::TripleBuffer::getUpToDateReadBuffer
const T & getUpToDateReadBuffer() const
Definition: TripleBuffer.h:116
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::core::CollisionAvoidanceBase::NodeSetData::rtRNS
VirtualRobot::RobotNodeSetPtr rtRNS
!!!!!!! Note that, all the data below should only be accessed in rt thread !!!!!!!
Definition: CollisionAvoidanceCore.h:73
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtCollisionChecking
void rtCollisionChecking()
Definition: CollisionAvoidanceCore.cpp:188
armarx::control::njoint_controller::core::CollisionAvoidanceBase::Config
law::arondto::CollisionAvoidanceConfigDict Config
Definition: CollisionAvoidanceCore.h:62
armarx::control::njoint_controller::core::CollisionAvoidanceBase::rtLimbControllerRun
void rtLimbControllerRun(const std::string &robotNodeSetName, const Eigen::VectorXf &qpos, const Eigen::VectorXf &qvelFiltered, float torqueLimit, const Eigen::VectorXf &impedanceJointTorque)
Definition: CollisionAvoidanceCore.cpp:225
armarx::TripleBuffer::reinitAllBuffers
std::enable_if< std::is_copy_constructible< U >::value >::type reinitAllBuffers(const T &init)
Definition: TripleBuffer.h:171
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19