CollisionAvoidanceHelper.cpp
Go to the documentation of this file.
2
3#include <SimoxUtility/algorithm/string/string_tools.h>
4#include <VirtualRobot/ManipulationObject.h>
5#include <VirtualRobot/XML/ObjectIO.h>
6#include <VirtualRobot/XML/RobotIO.h>
7
8#include <simox/control/environment/collision.h>
9#include <simox/control/impl/simox/utils/conversion.h>
10#include <simox/control/impl/simox/utils/primitive_conversion.h>
11
15
16#include <RobotAPI/interface/armem/server/ActionsInterface.h>
18
20{
21 const auto changeZtoYaxis = Eigen::AngleAxisd(-M_PI / 2., Eigen::Vector3d::UnitX());
22
23 armarx::control::common::control_law::arondto::CollisionScene
25 const std::map<std::string,
26 std::vector<simox::control::environment::TransformedCollisionObject>>&
27 collisionObjects)
28 {
29 auto scene = armarx::control::common::control_law::arondto::CollisionScene();
30 for (const auto& [fst, snd] : collisionObjects)
31 {
32 ARMARX_INFO << "adding " << snd.size() << " primitives for " << fst;
33 for (const auto& [collisionObject, localTransformation] : snd)
34 {
35 auto globalTransform = collisionObject.getTransform();
36 const auto& rot = globalTransform.getRotation();
37 const auto& trans = globalTransform.getTranslation();
38 Eigen::Matrix4d transformation = Eigen::Matrix4d::Identity();
39 transformation.block<3, 3>(0, 0) = rot;
40 transformation.block<3, 1>(0, 3) = trans;
41
42 switch (collisionObject.getNodeType())
43 {
44 case hpp::fcl::NODE_TYPE::GEOM_BOX:
45 {
46 auto box = armarx::control::common::control_law::arondto::Box();
47 // cast obj to Box
48 const hpp::fcl::CollisionGeometry* geomPtr =
49 collisionObject.collisionGeometry().get();
50 auto boxObj = dynamic_cast<const hpp::fcl::Box*>(geomPtr);
51 box.lengthX = boxObj->halfSide[0] * 2;
52 box.lengthZ = boxObj->halfSide[1] * 2;
53 box.lengthY = boxObj->halfSide[2] * 2;
54
55 box.transformation = transformation;
56
57 scene.boxes.push_back(box);
58 break;
59 }
60
61 case hpp::fcl::NODE_TYPE::GEOM_SPHERE:
62 {
63 auto sphere = armarx::control::common::control_law::arondto::Sphere();
64 // cast obj to Sphere
65 const hpp::fcl::CollisionGeometry* geomPtr =
66 collisionObject.collisionGeometry().get();
67 auto sphereObj = dynamic_cast<const hpp::fcl::Sphere*>(geomPtr);
68 sphere.radius = sphereObj->radius;
69
70 sphere.transformation = transformation;
71
72 scene.spheres.push_back(sphere);
73 break;
74 }
75
76 case hpp::fcl::NODE_TYPE::GEOM_CYLINDER:
77 {
78 auto cylinder = armarx::control::common::control_law::arondto::Cylinder();
79 // cast obj to Cylinder
80 const hpp::fcl::CollisionGeometry* geomPtr =
81 collisionObject.collisionGeometry().get();
82 auto cylinderObj = dynamic_cast<const hpp::fcl::Cylinder*>(geomPtr);
83 cylinder.radius = cylinderObj->radius;
84 cylinder.lengthY = cylinderObj->halfLength * 2;
85
86 transformation.block<3, 3>(0, 0) = rot * changeZtoYaxis;
87 cylinder.transformation = transformation;
88
89 scene.cylinders.push_back(cylinder);
90 break;
91 }
92
93 case hpp::fcl::NODE_TYPE::GEOM_CAPSULE:
94 {
95 auto capsule = armarx::control::common::control_law::arondto::Capsule();
96 // cast obj to Capsule
97 const hpp::fcl::CollisionGeometry* geomPtr =
98 collisionObject.collisionGeometry().get();
99 auto capsuleObj = dynamic_cast<const hpp::fcl::Capsule*>(geomPtr);
100 capsule.radius = capsuleObj->radius;
101 capsule.lengthY = capsuleObj->halfLength * 2;
102
103 transformation.block<3, 3>(0, 0) = rot * changeZtoYaxis;
104 capsule.transformation = transformation;
105
106 scene.capsules.push_back(capsule);
107 break;
108 }
109
110 case hpp::fcl::NODE_TYPE::GEOM_ELLIPSOID:
111 {
112 auto ellipsoid = armarx::control::common::control_law::arondto::Ellipsoid();
113 // cast obj to Ellipsoid
114 const hpp::fcl::CollisionGeometry* geomPtr =
115 collisionObject.collisionGeometry().get();
116 auto ellipsoidObj = dynamic_cast<const hpp::fcl::Ellipsoid*>(geomPtr);
117 ellipsoid.lengthX = static_cast<float>(ellipsoidObj->radii[0]) * 2.0F;
118 ellipsoid.lengthZ = static_cast<float>(ellipsoidObj->radii[1]) * 2.0F;
119 ellipsoid.lengthY = static_cast<float>(ellipsoidObj->radii[2]) * 2.0F;
120
121 ellipsoid.transformation = transformation;
122
123 scene.ellipsoids.push_back(ellipsoid);
124 break;
125 }
126
127 default:
128 // Handle unsupported shape or log warning
129 break;
130 }
131 }
132 }
133 return scene;
134 }
135
136 armarx::control::common::control_law::arondto::CollisionScene
138 const std::vector<armarx::ObjectID>& objectIDs,
140 armarx::armem::obj::instance::Reader& objectInstanceReader,
142 {
143 auto classes = objectClassReader.getObjectClasses(objectIDs);
144 std::map<std::string, std::vector<simox::control::environment::TransformedCollisionObject>>
145 collisionObjects;
146 for (const auto& id : objectIDs)
147 {
148 auto classIt = classes.find(id.getClassID());
149 if (classIt != classes.end())
150 {
151 const auto& classObj = classIt->second;
152 if (classObj.simoxXmlPath.serialize().package.empty())
153 {
154 ARMARX_INFO_S << "Skipping " << id << " due to empty simoxXmlPath";
155 continue;
156 }
157 std::filesystem::path simoxXmlPath = classObj.simoxXmlPath.toSystemPath();
158
159 // TODO remove line but path in ObjectMemory is currently wrong
160 simoxXmlPath = simox::alg::replace_all(
161 simoxXmlPath, "PriorKnowledgeData/PriorKnowledgeData", "PriorKnowledgeData");
162 auto manipulationObject =
163 VirtualRobot::ObjectIO::loadManipulationObject(simoxXmlPath);
164 ARMARX_CHECK_NOT_NULL(manipulationObject);
165
166 simox::control::utils::primitive::Model primitiveModel;
167
168 if (!id.instanceName().empty())
169 { // can only read ArticulatedObjectMemory for object instances
170
171 auto articulatedObject =
172 articulatedObjectReader.queryState(id.str(), Clock::Now(), std::nullopt);
173
174 if (articulatedObject.has_value() and
175 not classObj.articulatedSimoxXmlPath.serialize().package.empty())
176 {
177
178 auto robot = VirtualRobot::RobotIO::loadRobot(
179 classObj.articulatedSimoxXmlPath.toSystemPath().string());
180
181 robot->setJointValues(articulatedObject.value().jointMap);
182 // iterate over all children, get their primitives and transform and combine in the primitiveModel
183 std::function<void(VirtualRobot::SceneObjectPtr)> processAll =
184 [&](const VirtualRobot::SceneObjectPtr& sceneObject)
185 {
186 if (!sceneObject)
187 {
188 return;
189 }
190 for (const auto& primitive :
191 sceneObject->getPrimitiveApproximation().getModels(
192 std::vector<std::string>(), true))
193 {
194 // combine global transform of parent with local transform of primitive
195 primitive->transform =
196 sceneObject->getGlobalPose() * primitive->transform;
197 simox::control::simox::utils::convert(*primitive, primitiveModel);
198 }
199 for (const auto& child : sceneObject->getChildren())
200 {
201 processAll(child);
202 }
203 };
204 for (const auto& child : robot->getChildren())
205 {
206 processAll(child);
207 }
208 }
209 }
210
211 // get not articulated primitives from the manipulation object
212 for (const auto& primitive :
213 manipulationObject->getPrimitiveApproximation().getModels(
214 std::vector<std::string>(), true))
215 {
216 simox::control::simox::utils::convert(*primitive, primitiveModel);
217 }
218 if (id.instanceName() == "")
219 {
220 objectInstanceReader.queryLatestObjectInstances(id);
221
222 for (const auto& [instance, object] :
223 objectInstanceReader.queryLatestObjectInstances(id))
224 {
225 Eigen::Isometry3d globalPose =
226 simox::control::simox::utils::from_simox(object.objectPoseGlobal);
227 collisionObjects[instance] =
228 simox::control::environment::createCollisionObjects(primitiveModel,
229 globalPose);
230 }
231 }
232 else
233 {
234 auto pose = objectInstanceReader.queryLatestObjectInstance(id);
235
236 if (pose.has_value())
237 {
238 Eigen::Isometry3d globalPose =
239 simox::control::simox::utils::from_simox(pose.value().objectPoseGlobal);
240 collisionObjects[id.str()] =
241 simox::control::environment::createCollisionObjects(primitiveModel,
242 globalPose);
243 }
244 }
245 }
246 }
247 return getCollisionSceneFromCollisionObjects(collisionObjects);
248 }
249
250 armarx::control::common::control_law::arondto::CollisionScene
252 const std::vector<std::string>& objectIDs,
254 armarx::armem::obj::instance::Reader& objectInstanceReader,
256 {
257 std::vector<armarx::ObjectID> convertedObjectIDs;
258 for (const auto& id : objectIDs)
259 {
260 convertedObjectIDs.emplace_back(armarx::ObjectID(id));
261 }
263 convertedObjectIDs, objectClassReader, objectInstanceReader, articulatedObjectReader);
264 }
265
266} // namespace armarx::control::collision_avoidance::helpers
#define M_PI
Definition MathTools.h:17
std::string str(const T &t)
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition ObjectID.h:11
std::optional< robot_state::RobotState > queryState(const std::string &instanceName, const armem::Time &timestamp, const std::optional< std::string > &providerName) const
Definition Reader.cpp:262
std::map< armarx::ObjectID, armem::clazz::ObjectClass > getObjectClasses(const std::vector< armarx::ObjectID > &objectIDs)
Get object class information for object class IDs.
std::optional< objpose::ObjectPose > queryLatestObjectInstance(const ObjectID &instanceId)
std::map< std::string, objpose::ObjectPose > queryLatestObjectInstances(const ObjectID &classId)
#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.
Definition Logging.h:181
#define ARMARX_INFO_S
Definition Logging.h:202
armarx::control::common::control_law::arondto::CollisionScene getCollisionSceneFromMemory(const std::vector< armarx::ObjectID > &objectIDs, armarx::armem::obj::clazz::ClassReader &objectClassReader, armarx::armem::obj::instance::Reader &objectInstanceReader, armarx::armem::articulated_object::ArticulatedObjectReader &articulatedObjectReader)
armarx::control::common::control_law::arondto::CollisionScene getCollisionSceneFromCollisionObjects(const std::map< std::string, std::vector< simox::control::environment::TransformedCollisionObject > > &collisionObjects)