25#include <SimoxUtility/color/Color.h>
26#include <VirtualRobot/MathTools.h>
27#include <VirtualRobot/RobotNodeSet.h>
29#include <simox/control/environment/collision.h>
30#include <simox/control/geodesics/util.h>
31#include <simox/control/robot/NodeInterface.h>
32#include <simox/control/utils/primitive.h>
45#include <armarx/control/common/control_law/aron/CollisionPrimitives.aron.generated.h>
50 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
53 const NJointControllerConfigPtr& config,
55 NJointControllerType{
robotUnit, config, robot}
57 auto cfg = ConfigPtrT::dynamicCast(config);
59 userCfgWithColl = CollisionCtrlCfg::FromAron(cfg->config);
61 coll = std::make_shared<CollAvoidVelBase>(this->
rtGetRobot(), userCfgWithColl.coll);
62 collReady.store(
true);
67 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
75 arm->controller.run(arm->rtConfig, arm->rtStatus);
85 coll->rtLimbControllerRun(arm->kinematicChainName,
86 arm->rtStatus.jointPosition,
87 arm->rtStatus.qvelFiltered,
88 arm->rtConfig.velocityLimit,
89 arm->rtStatus.desiredJointVelocity,
92 arm->rtStatus.inertia =
coll->collLimb.at(arm->kinematicChainName).rts.inertia;
98 arm->rtStatus.nDoFTorque,
99 arm->rtStatus.nDoFVelocity,
100 arm->rtStatus.desiredJointTorque,
101 coll->collLimb.at(arm->kinematicChainName).rts.desiredJointVel);
105 this->limbRTSetTarget(arm,
106 arm->rtStatus.nDoFTorque,
107 arm->rtStatus.nDoFVelocity,
108 arm->rtStatus.desiredJointTorque,
109 arm->rtStatus.desiredJointVelocity);
113 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
116 const IceUtil::Time& sensorValuesTimestamp,
117 const IceUtil::Time& timeSinceLastIteration)
119 double deltaT = timeSinceLastIteration.toSecondsDouble();
122 if (collReady.load())
125 coll->updateRtConfigFromUser();
126 coll->updateRtCollisionObjects();
127 coll->rtCollisionChecking();
129 for (
auto& pair : this->limb)
131 this->limbRTUpdateStatus(pair.second, deltaT);
134 this->rtRunCoordinator(deltaT);
136 for (
auto& pair : this->limb)
138 limbRT(pair.second, deltaT);
142 this->hands->updateRTStatus(deltaT);
146 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
150 const Ice::Current& iceCurrent)
154 common::control_law::arondto::ObjectCollisionAvoidanceVelConfigDict::FromAron(dto);
155 coll->setUserCfg(cfg);
158 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
162 size_t numCollisionObjects = 0;
165 numCollisionObjects += pair.second.size();
168 std::vector<hpp::fcl::CollisionObject> allCollisionObjects;
169 allCollisionObjects.reserve(numCollisionObjects);
172 allCollisionObjects.insert(
173 allCollisionObjects.end(), pair.second.begin(), pair.second.end());
176 coll->updateUserCollisionObjects(allCollisionObjects);
179 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
182 const Ice::Current& iceCurrent)
184 coll->deleteUserCollisionObjects();
187 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
190 const std::string& primitiveSourceName,
191 const ::armarx::aron::data::dto::DictPtr& dto,
192 const Ice::Current& iceCurrent)
195 auto scene = common::control_law::arondto::CollisionScene::FromAron(dto);
196 auto boxes = scene.boxes;
197 auto spheres = scene.spheres;
198 auto cylinders = scene.cylinders;
199 auto capsules = scene.capsules;
200 auto ellipsoids = scene.ellipsoids;
204 collisionObjects.emplace(primitiveSourceName, std::vector<hpp::fcl::CollisionObject>());
206 std::vector<hpp::fcl::CollisionObject>& collisionObjectsOfSource =
208 collisionObjectsOfSource.clear();
209 collisionObjectsOfSource.reserve(boxes.size() + spheres.size() + cylinders.size() +
210 capsules.size() + ellipsoids.size());
212 for (
auto box : boxes)
214 collisionObjectsOfSource.push_back(simox::control::environment::createCollisionObject(
215 simox::control::utils::primitive::Box{
216 .lengthX = box.lengthX, .lengthY = box.lengthY, .lengthZ = box.lengthZ},
217 Eigen::Isometry3d{box.transformation}));
220 for (
auto sphere : spheres)
222 collisionObjectsOfSource.push_back(simox::control::environment::createCollisionObject(
223 simox::control::utils::primitive::Sphere{.radius = sphere.radius},
224 Eigen::Isometry3d{sphere.transformation}));
227 for (
auto cylinder : cylinders)
229 collisionObjectsOfSource.push_back(simox::control::environment::createCollisionObject(
230 simox::control::utils::primitive::Cylinder{.radius = cylinder.radius,
231 .lengthY = cylinder.lengthY},
232 Eigen::Isometry3d{cylinder.transformation}));
235 for (
auto capsule : capsules)
237 collisionObjectsOfSource.push_back(simox::control::environment::createCollisionObject(
238 simox::control::utils::primitive::Capsule{.radius = capsule.radius,
239 .lengthY = capsule.lengthY},
240 Eigen::Isometry3d{capsule.transformation}));
243 for (
auto ellipsoid : ellipsoids)
245 collisionObjectsOfSource.push_back(simox::control::environment::createCollisionObject(
246 simox::control::utils::primitive::Ellipsoid{.lengthX = ellipsoid.lengthX,
247 .lengthY = ellipsoid.lengthY,
248 .lengthZ = ellipsoid.lengthZ},
249 Eigen::Isometry3d{ellipsoid.transformation}));
255 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
260 if (not collReady.load())
264 return coll->userCfg.toAronDTO();
267 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
270 const ::armarx::aron::data::dto::DictPtr& dto,
271 const Ice::Current& iceCurrent)
273 NJointControllerType::updateConfig(dto);
274 userCfgWithColl = CollisionCtrlCfg::FromAron(dto);
276 coll->setUserCfg(userCfgWithColl.coll);
279 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
282 const Ice::Current& iceCurrent)
289 NJointControllerType::getConfig();
290 userCfgWithColl.limbs = this->userConfig.limbs;
291 userCfgWithColl.hands = this->userConfig.hands;
292 return userCfgWithColl.toAronDTO();
295 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
307 datafields[
"collDistanceThreshold"] =
new Variant(recoveryState.collDistanceThreshold);
308 datafields[
"collDistanceThresholdInit"] =
309 new Variant(recoveryState.collDistanceThresholdInit);
311 datafields[
"trackingError"] =
new Variant(rtStatus.trackingError);
323 const Eigen::VectorXf selfCollNullspace = rtStatus.selfCollNullSpace.diagonal();
324 const Eigen::VectorXf jointLimNullspace = rtStatus.jointLimNullSpace.diagonal();
347 datafields[
"collisionPairsNum"] =
new Variant(rtStatus.collisionPairsNum);
348 datafields[
"activeCollPairsNum"] =
new Variant(rtStatus.activeCollPairsNum);
350 datafields[
"collisionPairTime"] =
new Variant(rtStatus.collisionPairTime);
351 datafields[
"collisionTorqueTime"] =
new Variant(rtStatus.collisionTorqueTime);
352 datafields[
"jointLimitTorqueTime"] =
new Variant(rtStatus.jointLimitTorqueTime);
353 datafields[
"selfCollNullspaceTime"] =
new Variant(rtStatus.selfCollNullspaceTime);
354 datafields[
"jointLimitNullspaceTime"] =
new Variant(rtStatus.jointLimitNullspaceTime);
356 datafields[
"impForceRatio"] =
new Variant(rtStatus.impForceRatio);
357 datafields[
"impTorqueRatio"] =
new Variant(rtStatus.impTorqueRatio);
373 for (
unsigned int i = 0; i < rtStatus.activeCollPairsNum; ++i)
402 datafields[std::to_string(i) +
"_minDistance"] =
403 new Variant(rtStatus.collDataVec[i].minDistance);
404 datafields[std::to_string(i) +
"_repVel"] =
405 new Variant(rtStatus.collDataVec[i].repulsiveVel);
406 datafields[std::to_string(i) +
"_dampingForce"] =
new Variant(
407 -1.0f * rtStatus.collDataVec[i].damping * rtStatus.collDataVec[i].distanceVelocity);
408 datafields[std::to_string(i) +
"_n_des(d)"] =
409 new Variant(rtStatus.collDataVec[i].desiredNSColl);
411 datafields, std::to_string(i) +
"_point", rtStatus.collDataVec[i].point1);
413 datafields, std::to_string(i) +
"_dir", rtStatus.collDataVec[i].direction);
698 debugObs->setDebugChannel(
"CollAvoid_ImpCtrl_" + arm.
nodeSetName, datafields);
701 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
704 const std::vector<hpp::fcl::CollisionObject>&
objects,
706 const std::string& layerSuffix)
710 for (
size_t i = 0; i <
objects.size(); ++i)
713 const auto position =
object.getTranslation().cast<
float>() * 1000;
714 const Eigen::Matrix3f rotation =
object.getRotation().cast<
float>();
716 switch (
object.getNodeType())
718 case hpp::fcl::NODE_TYPE::GEOM_BOX:
720 const hpp::fcl::Box* box =
721 std::static_pointer_cast<hpp::fcl::Box>(
object.collisionGeometry()).get();
723 .
size(box->halfSide.cast<
float>() * 1000 * 2)
726 .
color(255, 0, 0, 128);
727 objectLayer.
add(vizObject);
730 case hpp::fcl::NODE_TYPE::GEOM_SPHERE:
732 const hpp::fcl::Sphere* sphere =
733 std::static_pointer_cast<hpp::fcl::Sphere>(
object.collisionGeometry())
737 .
radius(
static_cast<float>(sphere->radius) * 1000)
740 .
color(0, 0, 255, 128);
741 objectLayer.
add(vizObject);
744 case hpp::fcl::NODE_TYPE::GEOM_CYLINDER:
746 const hpp::fcl::Cylinder* cylinder =
747 std::static_pointer_cast<hpp::fcl::Cylinder>(
object.collisionGeometry())
751 .
height(
static_cast<float>(cylinder->halfLength) * 1000 * 2)
752 .
radius(
static_cast<float>(cylinder->radius) * 1000)
754 Eigen::AngleAxisf(
M_PI / 2., Eigen::Vector3f::UnitX()))
756 .
color(0, 255, 0, 128);
757 objectLayer.
add(vizObject);
760 case hpp::fcl::NODE_TYPE::GEOM_CAPSULE:
762 const hpp::fcl::Capsule* capsule =
763 std::static_pointer_cast<hpp::fcl::Capsule>(
object.collisionGeometry())
765 const auto _rotation =
766 rotation * Eigen::AngleAxisf(
M_PI / 2., Eigen::Vector3f::UnitX());
767 Eigen::Vector3f offset;
768 offset << 0, static_cast<float>(capsule->halfLength) * 1000, 0;
769 offset = _rotation * offset;
772 .
radius(
static_cast<float>(capsule->radius) * 1000)
775 .
color(255, 200, 0, 128);
777 .
radius(
static_cast<float>(capsule->radius) * 1000)
780 .
color(255, 200, 0, 128);
783 .
height(
static_cast<float>(capsule->halfLength) * 1000 * 2)
784 .
radius(
static_cast<float>(capsule->radius) * 1000)
785 .
color(255, 200, 0, 128)
788 objectLayer.
add(vizObject);
789 objectLayer.
add(cap1);
790 objectLayer.
add(cap2);
793 case hpp::fcl::NODE_TYPE::GEOM_ELLIPSOID:
795 const hpp::fcl::Ellipsoid* ellipsoid =
796 std::static_pointer_cast<hpp::fcl::Ellipsoid>(
object.collisionGeometry())
801 .
axisLengths(ellipsoid->radii.cast<
float>() * 1000)
804 .
color(255, 0, 200, 128);
805 objectLayer.
add(vizObject);
811 arviz.commit(objectLayer);
814 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
821 NJointControllerType::onPublish(sc, drawer, debugObs);
824 for (
auto& pair :
coll->collLimb)
831 const auto& robotObjects =
coll->collisionRobot->getCollisionManager()->getObjects();
832 std::vector<hpp::fcl::CollisionObject> robotObjectsByValue;
833 for (
const auto* ptr : robotObjects)
835 robotObjectsByValue.push_back(*ptr);
841 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
847 NJointControllerType::rtPreActivateController();
849 if (collReady.load())
852 coll->rtPreActivate();
856 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
861 NJointControllerType::rtPostDeactivateController();
862 if (collReady.load())
865 coll->rtPostDeactivate();
871 template <
typename NJo
intControllerType,
typename CollisionCtrlCfg>
876 auto cfgName = values.at(
"config_box")->getString();
879 "controller_config/" + std::string(NJointControllerType::ControlType::TypeName) +
880 "Col/" + cfgName +
".json");
887 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};
892 law::arondto::TSVelColConfigDict>;
898 const NJointControllerConfigPtr& config,
armarx::viz::Client arviz
std::string getName() const
Retrieve name of object.
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
static std::filesystem::path toSystemPath(const data::PackagePath &pp)
const T & getUpToDateReadBuffer() const
The Variant class is described here: Variants.
void collObjectPublish(const std::vector< hpp::fcl::CollisionObject > &objects, const DebugObserverInterfacePrx &debugObs, const std::string &layerSuffix)
void collLimbPublish(CollAvoidVelBase::NodeSetData &arm, const DebugObserverInterfacePrx &debugObs)
void limbRT(ArmPtr &arm, const double deltaT)
void sendCollisionObjects()
std::map< std::string, std::vector< hpp::fcl::CollisionObject > > collisionObjects
void rtPostDeactivateController() override
void updateCollisionAvoidanceConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
NJointController interface for collision avoidance.
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
void updateCollisionObjects(const std::string &primitiveSourceName, const ::armarx::aron::data::dto::DictPtr &scene, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
typename NJointControllerType::ConfigPtrT ConfigPtrT
static ConfigPtrT GenerateConfigFromVariants(const StringVariantBaseMap &values)
void onPublish(const SensorAndControl &sc, const DebugDrawerInterfacePrx &drawer, const DebugObserverInterfacePrx &) override
typename NJointTSVelController::ArmPtr ArmPtr
::armarx::aron::data::dto::DictPtr getConfig(const Ice::Current &iceCurrent) override
NJointTSVelBasedColController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
void rtPreActivateController() override
NJointControllerBase interface.
void updateConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent) override
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override
NJointTSVelColController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
void limbRTSetTarget(ArmPtr &arm, const size_t nDoFTorque, const size_t nDoFVelocity, const Eigen::VectorXf &targetTorque, const Eigen::VectorXf &targetVelocity)
DerivedT & color(Color color)
DerivedT & position(float x, float y, float z)
DerivedT & orientation(Eigen::Quaternionf const &ori)
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
armarx::aron::data::dto::Dict getCollisionAvoidanceConfig()
void deleteCollisionObjects()
std::shared_ptr< class Robot > RobotPtr
::IceInternal::Handle< Dict > DictPtr
void debugEigenVec(StringVariantBaseMap &datafields, const std::string &name, Eigen::VectorXf vec)
NJointControllerRegistration< NJointTSVelColController > registrationControllerNJointTSVelColController("TSVelCol")
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
AronDTO readFromJson(const std::filesystem::path &filename)
IceUtil::Handle< class RobotUnit > RobotUnitPtr
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
detail::ControlThreadOutputBufferEntry SensorAndControl
armarx::TripleBuffer< RecoveryState > bufferRecoveryStateSelfColl
armarx::TripleBuffer< RtStatus > bufferRTtoPublish
Box & size(Eigen::Vector3f const &s)
Cylinder & height(float h)
Cylinder & radius(float r)
Ellipsoid & axisLengths(const Eigen::Vector3f &axisLengths)
void add(ElementT const &element)