39 #include <pybind11/eigen.h>
40 #include <pybind11/pybind11.h>
41 #include <pybind11/stl.h>
48 #include <unsupported/Eigen/CXX11/Tensor>
50 #if PY_MAJOR_VERSION < 3
51 #define PY_OLDSTANDARD
54 #ifndef PY_OLDSTANDARD
55 bool PyInt_Check(PyObject* value_py) {
return PyLong_Check(value_py); }
56 long PyInt_AsLong(PyObject* value_py) {
return PyLong_AsLong(value_py); }
61 #ifndef PY_OLDSTANDARD
62 return PyUnicode_Check(value_py);
64 return PyString_Check(value_py) || PyUnicode_Check(value_py);
70 #ifndef PY_OLDSTANDARD
71 PyObject* tmp = PyUnicode_AsASCIIString(value_py);
76 return std::string(PyString_AsString(value_py));
82 #ifndef PY_OLDSTANDARD
83 return PyUnicode_DecodeASCII(value.c_str(), value.size(),
"");
85 return PyString_FromString(value.c_str());
96 #if PY_MAJOR_VERSION <= 2
97 PyObject* module = PyImport_ImportModule(
"StringIO");
98 if (!module)
ThrowPretty(
"Can't load StringIO module.");
99 PyObject* cls = PyObject_GetAttrString(module,
"StringIO");
100 if (!cls)
ThrowPretty(
"Can't load StringIO class.");
102 PyObject* module = PyImport_ImportModule(
"io");
104 PyObject* cls = PyObject_GetAttrString(module,
"BytesIO");
105 if (!cls)
ThrowPretty(
"Can't load BytesIO class.");
107 PyObject* stringio = PyObject_CallObject(cls, NULL);
108 if (!stringio)
ThrowPretty(
"Can't create StringIO object.");
114 #define ROS_MESSAGE_WRAPPER(MessageType) \
120 struct type_caster<MessageType> \
123 PYBIND11_TYPE_CASTER(MessageType, _("genpy.Message")); \
125 bool load(handle src, bool) \
127 PyObject* stringio = CreateStringIOObject(); \
128 if (!stringio) ThrowPretty("Can't create StringIO instance."); \
130 PyObject_CallMethod(src.ptr(), "serialize", "O", stringio); \
131 if (!result) ThrowPretty("Can't serialize."); \
132 result = PyObject_CallMethod(stringio, "getvalue", nullptr); \
133 if (!result) ThrowPretty("Can't get buffer."); \
134 char* data = PyByteArray_AsString(PyByteArray_FromObject(result)); \
135 int len = PyByteArray_Size(result); \
136 unsigned char* udata = new unsigned char[len]; \
137 for (int i = 0; i < len; ++i) \
138 udata[i] = static_cast<unsigned char>(data[i]); \
139 ros::serialization::IStream stream(udata, len); \
140 ros::serialization::deserialize<MessageType>(stream, value); \
143 Py_DECREF(stringio); \
145 return !PyErr_Occurred(); \
148 static handle cast(MessageType src, \
149 return_value_policy ) \
151 ros::message_traits::DataType<MessageType::Type> type; \
152 ThrowPretty("Can't create python object from message of type '" \
153 << type.value() << "'!"); \
158 #include <moveit_msgs/PlanningScene.h>
159 #include <moveit_msgs/PlanningSceneWorld.h>
168 std::pair<Initializer, Initializer>
LoadFromXML(std::string file_name,
const std::string& solver_name =
"",
const std::string& problem_name =
"",
bool parsePathAsXML =
false)
171 XMLLoader::Load(file_name, solver, problem, solver_name, problem_name, parsePathAsXML);
172 return std::pair<Initializer, Initializer>(solver, problem);
177 py::module inits = module.def_submodule(
"Initializers",
"Initializers for core EXOTica classes.");
182 const std::string full_name = i.GetName();
183 const std::string
name = full_name.substr(8);
188 inits.def(
"load_xml", (
Initializer(*)(std::string, bool)) &
XMLLoader::Load,
"Loads initializer from XML", py::arg(
"xml"), py::arg(
"parseAsXMLString") =
false);
189 inits.def(
"load_xml_full", &
LoadFromXML,
"Loads initializer from XML", py::arg(
"xml"), py::arg(
"solver_name") = std::string(
""), py::arg(
"problem_name") = std::string(
""), py::arg(
"parseAsXMLString") =
false);
200 PYBIND11_TYPE_CASTER(
Initializer, _(
"Initializer"));
209 else if (target.
GetType() ==
"int")
216 else if (PyInt_Check(value_py) || PyLong_Check(value_py))
218 target.
Set((
int)PyInt_AsLong(value_py));
222 else if (target.
GetType() ==
"long")
229 else if (PyInt_Check(value_py))
231 target.
Set(PyInt_AsLong(value_py));
236 ThrowPretty(
"to be implemented - please open an issue.");
239 else if (target.
GetType() ==
"double")
246 else if (PyFloat_Check(value_py))
248 target.
Set(PyFloat_AsDouble(value_py));
252 else if (target.
GetType() ==
"Eigen::Matrix<double, -1, 1, 0, -1, 1>")
260 target.
Set(py::cast<Eigen::VectorXd>(value_py));
264 else if (target.
GetType() ==
"Eigen::Matrix<int, -1, 1, 0, -1, 1>")
272 target.
Set(py::cast<Eigen::VectorXi>(value_py));
276 else if (target.
GetType() ==
"Eigen::Matrix<double, 2, 1, 0, 2, 1>")
284 target.
Set(py::cast<Eigen::Vector2d>(value_py));
288 else if (target.
GetType() ==
"Eigen::Matrix<double, 3, 1, 0, 3, 1>")
296 target.
Set(py::cast<Eigen::Vector3d>(value_py));
308 target.
Set(py::cast<std::vector<int>>(value_py));
320 target.
Set(py::cast<std::vector<std::string>>(value_py));
324 else if (target.
GetType() ==
"bool")
331 else if (PyBool_Check(value_py))
333 target.
Set(PyObject_IsTrue(value_py) == 1);
337 else if (target.
GetType() ==
"exotica::Initializer")
339 if (PyList_Check(value_py))
342 int n = PyList_Size(value_py);
345 if (!PyToInit(PyList_GetItem(value_py, 0), tmp))
347 WARNING(
"Could not create initializer :'(");
353 WARNING(
"List size is greater than 1 - this should not happen: " <<
n);
360 if (!PyToInit(value_py, tmp))
362 WARNING(
"Could not convert Python value to exotica::Initializer");
371 if (PyList_Check(value_py))
373 int n = PyList_Size(value_py);
374 std::vector<Initializer> vec(
n);
375 for (
int i = 0; i <
n; ++i)
377 if (!PyToInit(PyList_GetItem(value_py, i), vec[i]))
379 WARNING(
"Could not parse initializer in vector of initializers: #" << i);
388 HIGHLIGHT(
"InitializerVectorType failed PyList_Check");
401 if (!PyTuple_CheckExact(source))
407 int tuple_size = PyTuple_Size(source);
408 if (tuple_size < 1 || tuple_size > 2)
410 WARNING_NAMED(
"PyToInit",
"Wrong sized tuple for exotica::Initializer: " << tuple_size);
414 PyObject*
const name_py = PyTuple_GetItem(source, 0);
417 WARNING_NAMED(
"PyToInit",
"First element of exotica::Initializer-tuple is not a string.");
425 HIGHLIGHT(
"Unknown initializer type '" << initializer_name <<
"'");
432 PyObject*
const dict = PyTuple_GetItem(source, 1);
433 if (!PyDict_Check(dict))
435 WARNING_NAMED(
"PyToInit",
"Second element of exotica::Initializer-tuple is not a dict.");
439 PyObject *key, *value_py;
442 while (PyDict_Next(dict, &pos, &key, &value_py))
448 if (!AddPropertyFromDict(ret.
properties_.at(key_str), value_py))
450 HIGHLIGHT(
"Failed to add property '" << key_str <<
"'");
470 return PyToInit(src.ptr(), value);
475 PyObject* dict = PyDict_New();
478 addPropertyToDict(dict, prop.first, prop.second);
481 PyObject* tup = PyTuple_Pack(2,
name, dict);
491 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<std::string>(prop.
Get())).ptr());
493 else if (prop.
GetType() ==
"int")
495 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<int>(prop.
Get())).ptr());
497 else if (prop.
GetType() ==
"long")
499 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<long>(prop.
Get())).ptr());
501 else if (prop.
GetType() ==
"double")
503 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<double>(prop.
Get())).ptr());
505 else if (prop.
GetType() ==
"Eigen::Matrix<double, -1, 1, 0, -1, 1>")
507 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<Eigen::VectorXd>(prop.
Get())).ptr());
509 else if (prop.
GetType() ==
"Eigen::Matrix<int, -1, 1, 0, -1, 1>")
511 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<Eigen::VectorXi>(prop.
Get())).ptr());
513 else if (prop.
GetType() ==
"Eigen::Matrix<double, 2, 1, 0, 2, 1>")
515 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<Eigen::Vector2d>(prop.
Get())).ptr());
517 else if (prop.
GetType() ==
"Eigen::Matrix<double, 3, 1, 0, 3, 1>")
519 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<Eigen::Vector3d>(prop.
Get())).ptr());
523 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<std::vector<int>>(prop.
Get())).ptr());
527 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<std::vector<std::string>>(prop.
Get())).ptr());
529 else if (prop.
GetType() ==
"bool")
531 PyDict_SetItemString(dict,
name.c_str(), py::cast(boost::any_cast<bool>(prop.
Get())).ptr());
533 else if (prop.
GetType() ==
"exotica::Initializer")
535 PyObject*
init = InitializerToTuple(boost::any_cast<Initializer>(prop.
Get()));
536 PyDict_SetItemString(dict,
name.c_str(),
init);
541 PyObject* vec = PyList_New(0);
542 for (
Initializer& i : boost::any_cast<std::vector<Initializer>>(prop.
Get()))
544 PyObject*
init = InitializerToTuple(i);
545 PyList_Append(vec,
init);
548 PyDict_SetItemString(dict,
name.c_str(), vec);
559 return handle(InitializerToTuple(src));
567 pybind11::array_t<T> inArray)
570 pybind11::buffer_info buffer_info = inArray.request();
573 T* data =
static_cast<T*
>(buffer_info.ptr);
574 std::vector<ssize_t> shape = buffer_info.shape;
579 Eigen::TensorMap<Eigen::Tensor<T, 3, Eigen::RowMajor>> in_tensor(
580 data, shape[0], shape[1], shape[2]);
582 Hessian hessian = Hessian::Constant(shape[0], Eigen::MatrixXd::Zero(shape[1], shape[2]));
583 for (
int i = 0; i < shape[0]; i++)
585 for (
int j = 0; j < shape[1]; j++)
587 for (
int k = 0; k < shape[2]; k++)
589 hessian(i)(j, k) = in_tensor(i, j, k);
600 std::vector<ssize_t> shape(3);
601 shape[0] = inp.rows();
604 shape[1] = inp(0).rows();
605 shape[2] = inp(0).cols();
609 shape[1] = shape[2] = 0;
612 pybind11::array_t<T> array(
614 {shape[1] * shape[2] *
sizeof(T), shape[2] *
sizeof(T),
sizeof(T)});
616 Eigen::TensorMap<Eigen::Tensor<T, 3, Eigen::RowMajor>> in_tensor(
617 array.mutable_data(), shape[0], shape[1], shape[2]);
618 for (
int i = 0; i < shape[0]; i++)
620 for (
int j = 0; j < shape[1]; j++)
622 for (
int k = 0; k < shape[2]; k++)
624 in_tensor(i, j, k) = inp(i)(j, k);
628 return array.release();
644 PYBIND11_TYPE_CASTER(
Hessian, _(
"Hessian"));
653 value =
array_hessian(py::cast<pybind11::array_t<Hessian::Scalar::Scalar>>(src.ptr()));
666 return hessian_array<Hessian::Scalar::Scalar>(src);
674 module.doc() =
"Exotica Python wrapper";
676 py::class_<Setup, std::unique_ptr<Setup, py::nodelete>>
setup(module,
"Setup");
688 setup.def_static(
"get_initializers", &
Setup::GetInitializers, py::return_value_policy::copy,
"Returns a list of available initializers with all available parameters/arguments.");
690 setup.def_static(
"init_ros",
691 [](
const std::string&
name,
const bool& anonymous) {
703 "Initializes an internal ROS node for publishing debug information from Exotica (i.e., activates ROS features). Options are setting the name and whether to spawn an anonymous node.",
704 py::arg(
"name") =
"exotica", py::arg(
"anonymous") =
false);
705 setup.def_static(
"load_solver", &
XMLLoader::LoadSolver,
"Instantiate solver and problem from an XML file containing both a solver and problem initializer.", py::arg(
"filepath"));
706 setup.def_static(
"load_solver_standalone", &
XMLLoader::LoadSolverStandalone,
"Instantiate only a solver from an XML file containing solely a solver initializer.", py::arg(
"filepath"));
707 setup.def_static(
"load_problem", &
XMLLoader::LoadProblem,
"Instantiate only a problem from an XML file containing solely a problem initializer.", py::arg(
"filepath"));
709 py::module tools = module.def_submodule(
"Tools");
713 tools.def(
"parse_vector", &ParseVector<double, Eigen::Dynamic>);
717 tools.def(
"load_obj", [](
const std::string& path) { Eigen::VectorXi tri; Eigen::VectorXd vert;
LoadOBJ(
LoadFile(path), tri, vert);
return py::make_tuple(tri, vert); });
728 py::arg(
"data"), py::arg(
"max_radius") = 1.0);
730 py::module sparse_costs = tools.def_submodule(
"SparseCosts")
741 py::class_<Timer, std::shared_ptr<Timer>> timer(module,
"Timer");
742 timer.def(py::init());
746 py::class_<Object, std::shared_ptr<Object>> object(module,
"Object");
747 object.def_property_readonly(
"type", &
Object::type,
"Object type");
749 object.def(
"__repr__", &
Object::Print,
"String representation of the object", py::arg(
"prepend") = std::string(
""));
753 py::enum_<TerminationCriterion>(module,
"TerminationCriterion")
765 py::enum_<RotationType>(module,
"RotationType")
774 py::enum_<BaseType>(module,
"BaseType")
775 .value(
"Fixed", BaseType::FIXED)
776 .value(
"Floating", BaseType::FLOATING)
777 .value(
"Planar", BaseType::PLANAR)
780 py::class_<KDL::Frame> kdl_frame(module,
"KDLFrame");
781 kdl_frame.def(py::init());
782 kdl_frame.def(py::init([](Eigen::MatrixXd other) {
return GetFrameFromMatrix(other); }));
783 kdl_frame.def(py::init([](Eigen::VectorXd other) {
return GetFrame(other); }));
784 kdl_frame.def(py::init([](
const KDL::Frame& other) {
return KDL::Frame(other); }));
785 kdl_frame.def(
"__repr__", [](KDL::Frame* me) {
return "KDL::Frame " +
ToString(*me); });
791 kdl_frame.def(
"get_translation", [](KDL::Frame* me) { Eigen::Vector3d tmp;
for (
int i = 0; i < 3; ++i) { tmp[i] = me->p.data[i]; }
return tmp; });
797 kdl_frame.def(
"get_frame", [](KDL::Frame* me) {
return GetFrame(*me); });
798 kdl_frame.def(
"inverse", (KDL::Frame(KDL::Frame::*)()
const) & KDL::Frame::Inverse);
799 kdl_frame.def(
"__mul__", [](
const KDL::Frame&
A,
const KDL::Frame& B) {
return A * B; }, py::is_operator());
800 kdl_frame.def_readwrite(
"p", &KDL::Frame::p);
801 kdl_frame.def_static(
"interpolate", [](KDL::Frame*
A, KDL::Frame* B,
double alpha) {
return KDL::addDelta(*
A, KDL::diff(*
A, *B) * alpha); });
802 kdl_frame.def_static(
"diff", [](KDL::Frame*
A, KDL::Frame* B) { Eigen::VectorXd ret(6); KDL::Twist
t = KDL::diff(*
A, *B);
for(
int i=0; i<6; ++i) ret(i) =
t[i];
return ret; });
803 py::implicitly_convertible<Eigen::MatrixXd, KDL::Frame>();
804 py::implicitly_convertible<Eigen::VectorXd, KDL::Frame>();
806 py::class_<KDL::Vector>(module,
"KDLVector")
808 .def(py::init<double, double, double>(),
812 .def(
"__repr__", [](KDL::Vector* me) {
return "KDL::Vector [" + std::to_string(me->data[0]) +
", " + std::to_string(me->data[1]) +
", " + std::to_string(me->data[2]) +
"]"; })
813 .def(
"x", [](KDL::Vector& v) ->
double& {
return v[0]; })
814 .def(
"y", [](KDL::Vector& v) ->
double& {
return v[1]; })
815 .def(
"z", [](KDL::Vector& v) ->
double& {
return v[2]; })
816 .def_static(
"Zero", &KDL::Vector::Zero);
818 py::class_<KDL::RotationalInertia>(module,
"KDLRotationalInertia")
819 .def(py::init<double, double, double, double, double, double>(),
826 .def_static(
"Zero", &KDL::RotationalInertia::Zero);
828 py::class_<KDL::RigidBodyInertia>(module,
"KDLRigidBodyInertia")
829 .def(py::init<double, KDL::Vector&, KDL::RotationalInertia&>(),
831 py::arg(
"oc") = KDL::Vector::Zero(),
832 py::arg(
"Ic") = KDL::RotationalInertia::Zero())
833 .def_static(
"Zero", &KDL::RigidBodyInertia::Zero);
835 py::class_<TaskMap, std::shared_ptr<TaskMap>,
Object>(module,
"TaskMap")
844 py::class_<TaskIndexing>(module,
"TaskIndexing")
851 py::class_<TimeIndexedTask, std::shared_ptr<TimeIndexedTask>>(module,
"TimeIndexedTask")
878 py::class_<EndPoseTask, std::shared_ptr<EndPoseTask>>(module,
"EndPoseTask")
898 py::class_<SamplingTask, std::shared_ptr<SamplingTask>>(module,
"SamplingTask")
913 py::class_<TaskSpaceVector, std::shared_ptr<TaskSpaceVector>> task_space_vector(module,
"TaskSpaceVector");
916 task_space_vector.def(
"__sub__", &TaskSpaceVector::operator-, py::is_operator());
917 task_space_vector.def(
"__repr__", [](
TaskSpaceVector* instance) {
return ((std::ostringstream&)(std::ostringstream(
"") <<
"TaskSpaceVector (" << instance->
data.transpose() <<
")")).str(); });
919 py::class_<MotionSolver, std::shared_ptr<MotionSolver>,
Object> motion_solver(module,
"MotionSolver");
924 "solve", [](std::shared_ptr<MotionSolver> sol) {
929 "Solve the problem");
932 py::class_<FeedbackMotionSolver, std::shared_ptr<FeedbackMotionSolver>,
MotionSolver> feedback_motion_solver(module,
"FeedbackMotionSolver");
935 py::class_<PlanningProblem, std::shared_ptr<PlanningProblem>,
Object>(module,
"PlanningProblem")
939 .def(
"__repr__", &
PlanningProblem::Print,
"String representation of the object", py::arg(
"prepend") = std::string(
""))
956 py::module prob = module.def_submodule(
"Problems",
"Problem types");
958 py::class_<UnconstrainedTimeIndexedProblem, std::shared_ptr<UnconstrainedTimeIndexedProblem>,
PlanningProblem> unconstrained_time_indexed_problem(prob,
"UnconstrainedTimeIndexedProblem");
981 py::class_<TimeIndexedProblem, std::shared_ptr<TimeIndexedProblem>,
PlanningProblem> time_indexed_problem(prob,
"TimeIndexedProblem");
1028 py::class_<BoundedTimeIndexedProblem, std::shared_ptr<BoundedTimeIndexedProblem>,
PlanningProblem> bounded_time_indexed_problem(prob,
"BoundedTimeIndexedProblem");
1052 py::class_<UnconstrainedEndPoseProblem, std::shared_ptr<UnconstrainedEndPoseProblem>,
PlanningProblem> unconstrained_end_pose_problem(prob,
"UnconstrainedEndPoseProblem");
1072 py::class_<EndPoseProblem, std::shared_ptr<EndPoseProblem>,
PlanningProblem> end_pose_problem(prob,
"EndPoseProblem");
1106 py::class_<BoundedEndPoseProblem, std::shared_ptr<BoundedEndPoseProblem>,
PlanningProblem> bounded_end_pose_problem(prob,
"BoundedEndPoseProblem");
1124 py::class_<SamplingProblem, std::shared_ptr<SamplingProblem>,
PlanningProblem> sampling_problem(prob,
"SamplingProblem");
1143 py::class_<TimeIndexedSamplingProblem, std::shared_ptr<TimeIndexedSamplingProblem>,
PlanningProblem> time_indexed_sampling_problem(prob,
"TimeIndexedSamplingProblem");
1163 py::enum_<ControlCostLossTermType>(module,
"ControlCostLossTermType")
1165 .value(
"Undefined", ControlCostLossTermType::Undefined)
1166 .value(
"L2", ControlCostLossTermType::L2)
1167 .value(
"SmoothL1", ControlCostLossTermType::SmoothL1)
1168 .value(
"Huber", ControlCostLossTermType::Huber)
1169 .value(
"PseudoHuber", ControlCostLossTermType::PseudoHuber)
1172 py::class_<DynamicTimeIndexedShootingProblem, std::shared_ptr<DynamicTimeIndexedShootingProblem>,
PlanningProblem>(prob,
"DynamicTimeIndexedShootingProblem")
1196 py::class_<CollisionProxy, std::shared_ptr<CollisionProxy>> collision_proxy(module,
"CollisionProxy");
1197 collision_proxy.def(py::init());
1203 collision_proxy.def_property_readonly(
"object_1", [](
CollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e1->segment.getName() : std::string(
""); });
1204 collision_proxy.def_property_readonly(
"object_2", [](
CollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e2->segment.getName() : std::string(
""); });
1205 collision_proxy.def_property_readonly(
"transform_1", [](
CollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e1->frame : KDL::Frame(); });
1206 collision_proxy.def_property_readonly(
"transform_2", [](
CollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e2->frame : KDL::Frame(); });
1209 py::class_<ContinuousCollisionProxy, std::shared_ptr<ContinuousCollisionProxy>> continuous_collision_proxy(module,
"ContinuousCollisionProxy");
1210 continuous_collision_proxy.def(py::init());
1215 continuous_collision_proxy.def_property_readonly(
"object_1", [](
ContinuousCollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e1->segment.getName() : std::string(
""); });
1216 continuous_collision_proxy.def_property_readonly(
"object_2", [](
ContinuousCollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e2->segment.getName() : std::string(
""); });
1217 continuous_collision_proxy.def_property_readonly(
"transform_1", [](
ContinuousCollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e1->frame : KDL::Frame(); });
1218 continuous_collision_proxy.def_property_readonly(
"transform_2", [](
ContinuousCollisionProxy* instance) {
return (instance->
e1 && instance->
e2) ? instance->
e2->frame : KDL::Frame(); });
1221 py::class_<Scene, std::shared_ptr<Scene>,
Object> scene(module,
"Scene");
1228 scene.def(
"update", &
Scene::Update, py::arg(
"x"), py::arg(
"t") = 0.0);
1238 scene.def(
"get_tree_names", [](
Scene& scene) {
1239 std::vector<std::string> frame_names;
1242 frame_names.push_back(m.first);
1247 scene.def(
"set_model_state_map", (
void (
Scene::*)(
const std::map<std::string, double>&,
double,
bool)) &
Scene::SetModelState, py::arg(
"x"), py::arg(
"t") = 0.0, py::arg(
"update_trajectory") =
false);
1252 scene.def(
"load_scene",
1254 py::arg(
"scene_string"),
1255 py::arg(
"offset_transform") = kdl_frame(),
1256 py::arg(
"update_collision_scene") =
true);
1257 scene.def(
"load_scene_file",
1259 py::arg(
"file_name"),
1260 py::arg(
"offset_transform") = kdl_frame(),
1261 py::arg(
"update_collision_scene") =
true);
1264 scene.def(
"is_state_valid", [](
Scene* instance,
bool self,
double safe_distance) {
return instance->
GetCollisionScene()->IsStateValid(
self, safe_distance); }, py::arg(
"check_self_collision") =
true, py::arg(
"safe_distance") = 0.0);
1265 scene.def(
"is_collision_free", [](
Scene* instance,
const std::string& o1,
const std::string& o2,
double safe_distance) {
return instance->
GetCollisionScene()->IsCollisionFree(o1, o2, safe_distance); }, py::arg(
"object_1"), py::arg(
"object_2"), py::arg(
"safe_distance") = 0.0);
1266 scene.def(
"is_allowed_to_collide", [](
Scene* instance,
const std::string& o1,
const std::string& o2,
bool self) {
return instance->
GetCollisionScene()->IsAllowedToCollide(o1, o2,
self); }, py::arg(
"object_1"), py::arg(
"object_2"), py::arg(
"check_self_collision") =
true);
1267 scene.def(
"get_collision_distance", [](
Scene* instance,
bool self) {
return instance->
GetCollisionScene()->GetCollisionDistance(
self); }, py::arg(
"check_self_collision") =
true);
1268 scene.def(
"get_collision_distance", [](
Scene* instance,
const std::string& o1,
const std::string& o2) {
return instance->
GetCollisionScene()->GetCollisionDistance(o1, o2); }, py::arg(
"object_1"), py::arg(
"object_2"));
1269 scene.def(
"get_collision_distance",
1270 [](
Scene* instance,
const std::string& o1,
const bool&
self) {
1273 py::arg(
"object_1"), py::arg(
"check_self_collision") =
true);
1274 scene.def(
"get_collision_distance",
1275 [](
Scene* instance,
const std::vector<std::string>& objects,
const bool&
self) {
1278 py::arg(
"objects"), py::arg(
"check_self_collision") =
true);
1279 scene.def(
"update_planning_scene_world",
1280 [](
Scene* instance, moveit_msgs::PlanningSceneWorld& world) {
1281 moveit_msgs::PlanningSceneWorldConstPtr my_ptr(
1282 new moveit_msgs::PlanningSceneWorld(world));
1286 scene.def(
"get_collision_robot_links", [](
Scene* instance) {
return instance->
GetCollisionScene()->GetCollisionRobotLinks(); });
1287 scene.def(
"get_collision_world_links", [](
Scene* instance) {
return instance->
GetCollisionScene()->GetCollisionWorldLinks(); });
1292 scene.def(
"attach_object_local", (
void (
Scene::*)(
const std::string&
name,
const std::string& parent,
const Eigen::VectorXd& pose)) &
Scene::AttachObjectLocal);
1295 scene.def(
"fk", [](
Scene* instance,
const std::string& e1,
const KDL::Frame& o1,
const std::string& e2,
const KDL::Frame& o2) {
return instance->
GetKinematicTree().
FK(e1, o1, e2, o2); });
1296 scene.def(
"fk", [](
Scene* instance,
const std::string& e1,
const std::string& e2) {
return instance->
GetKinematicTree().
FK(e1, KDL::Frame(), e2, KDL::Frame()); });
1297 scene.def(
"fk", [](
Scene* instance,
const std::string& e1) {
return instance->
GetKinematicTree().
FK(e1, KDL::Frame(),
"", KDL::Frame()); });
1298 scene.def(
"jacobian", [](
Scene* instance,
const std::string& e1,
const KDL::Frame& o1,
const std::string& e2,
const KDL::Frame& o2) {
return instance->
GetKinematicTree().
Jacobian(e1, o1, e2, o2); });
1299 scene.def(
"jacobian", [](
Scene* instance,
const std::string& e1,
const std::string& e2) {
return instance->
GetKinematicTree().
Jacobian(e1, KDL::Frame(), e2, KDL::Frame()); });
1300 scene.def(
"jacobian", [](
Scene* instance,
const std::string& e1) {
return instance->
GetKinematicTree().
Jacobian(e1, KDL::Frame(),
"", KDL::Frame()); });
1301 scene.def(
"hessian", [](
Scene* instance,
const std::string& e1,
const KDL::Frame& o1,
const std::string& e2,
const KDL::Frame& o2) {
return instance->
GetKinematicTree().
Hessian(e1, o1, e2, o2); });
1302 scene.def(
"hessian", [](
Scene* instance,
const std::string& e1,
const std::string& e2) {
return instance->
GetKinematicTree().
Hessian(e1, KDL::Frame(), e2, KDL::Frame()); });
1303 scene.def(
"hessian", [](
Scene* instance,
const std::string& e1) {
return instance->
GetKinematicTree().
Hessian(e1, KDL::Frame(),
"", KDL::Frame()); });
1306 scene.def(
"add_trajectory_from_array",
1307 [](
Scene* instance,
const std::string& link,
const Eigen::MatrixXd& data,
double radius) {
1310 py::arg(
"link"), py::arg(
"data"), py::arg(
"radius"));
1311 scene.def(
"get_trajectory", [](
Scene* instance,
const std::string& link) {
return instance->
GetTrajectory(link)->ToString(); });
1314 scene.def(
"add_object", [](
Scene* instance,
const std::string&
name,
const KDL::Frame&
transform,
const std::string& parent,
const std::string& shape_resource_path,
const Eigen::Vector3d scale,
const Eigen::Vector4d color,
const bool update_collision_scene) { instance->
AddObject(
name,
transform, parent, shape_resource_path, scale, KDL::RigidBodyInertia::Zero(), color, update_collision_scene); },
1316 py::arg(
"transform") = KDL::Frame(),
1317 py::arg(
"parent") =
"",
1318 py::arg(
"shape_resource_path"),
1319 py::arg(
"scale") = Eigen::Vector3d::Ones(),
1320 py::arg(
"color") = Eigen::Vector4d(0.5, 0.5, 0.5, 1.0),
1321 py::arg(
"update_collision_scene") =
true);
1322 scene.def(
"add_object", (
void (
Scene::*)(
const std::string&,
const KDL::Frame&,
const std::string&,
shapes::ShapeConstPtr,
const KDL::RigidBodyInertia&,
const Eigen::Vector4d&,
const bool)) &
Scene::AddObject,
1324 py::arg(
"transform") = KDL::Frame(),
1325 py::arg(
"parent") = std::string(),
1327 py::arg(
"inertia") = KDL::RigidBodyInertia::Zero(),
1328 py::arg(
"color") = Eigen::Vector4d(0.5, 0.5, 0.5, 1.0),
1329 py::arg(
"update_collision_scene") =
true);
1332 py::arg(
"transform") = KDL::Frame(),
1334 py::arg(
"color") = Eigen::Vector4d(0.5, 0.5, 0.5, 1.0),
1335 py::arg(
"update_collision_scene") =
true);
1341 py::class_<CollisionScene, std::shared_ptr<CollisionScene>> collision_scene(module,
"CollisionScene");
1356 py::class_<VisualizationMoveIt> visualization_moveit(module,
"VisualizationMoveIt");
1357 visualization_moveit.def(py::init<ScenePtr>());
1359 #ifdef MSGPACK_FOUND
1360 py::class_<VisualizationMeshcat> visualization_meshcat(module,
"VisualizationMeshcat");
1361 visualization_meshcat.def(py::init<ScenePtr, const std::string&, bool, const std::string&>(), py::arg(
"scene"), py::arg(
"url"), py::arg(
"use_mesh_materials") =
true, py::arg(
"file_url") =
"");
1368 visualization_meshcat.def(
"set_property", py::overload_cast<const std::string&, const std::string&, const double&>(&
VisualizationMeshcat::SetProperty), py::arg(
"path"), py::arg(
"property"), py::arg(
"value"));
1369 visualization_meshcat.def(
"set_property", py::overload_cast<const std::string&, const std::string&, const std::string&>(&
VisualizationMeshcat::SetProperty), py::arg(
"path"), py::arg(
"property"), py::arg(
"value"));
1370 visualization_meshcat.def(
"set_property", py::overload_cast<const std::string&, const std::string&, const bool&>(&
VisualizationMeshcat::SetProperty), py::arg(
"path"), py::arg(
"property"), py::arg(
"value"));
1371 visualization_meshcat.def(
"set_property", py::overload_cast<const std::string&, const std::string&, const Eigen::Vector3d&>(&
VisualizationMeshcat::SetProperty), py::arg(
"path"), py::arg(
"property"), py::arg(
"value"));
1372 visualization_meshcat.def(
"set_property", py::overload_cast<const std::string&, const std::string&, const Eigen::Vector4d&>(&
VisualizationMeshcat::SetProperty), py::arg(
"path"), py::arg(
"property"), py::arg(
"value"));
1375 py::module kin = module.def_submodule(
"Kinematics",
"Kinematics submodule.");
1376 py::class_<KinematicTree, std::shared_ptr<KinematicTree>> kinematic_tree(kin,
"KinematicTree");
1420 auto tree_weak_ptr = kt->
GetTree();
1421 std::vector<std::shared_ptr<KinematicElement>> tree_shared_ptr;
1422 tree_shared_ptr.reserve(tree_weak_ptr.size());
1423 for (
auto e : tree_weak_ptr)
1424 tree_shared_ptr.emplace_back(e.lock());
1425 return tree_shared_ptr;
1429 py::class_<KinematicElement, std::shared_ptr<KinematicElement>> kinematic_element(kin,
"KinematicElement");
1432 kinematic_element.def(
"get_segment_name", [](
KinematicElement* element) {
return element->
segment.getName(); });
1434 kinematic_element.def(
"get_parent_name", [](
KinematicElement* element) {
auto parent = element->
parent.lock();
if (parent) {
return parent->segment.getName(); }
else {
return std::string(
"no_parent"); } });
1435 kinematic_element.def(
"get_mass", [](
KinematicElement* element) {
return element->
segment.getInertia().getMass(); });
1448 py::class_<KinematicResponse, std::shared_ptr<KinematicResponse>> kinematic_response(kin,
"KinematicResponse");
1449 kinematic_response.def_property_readonly(
"Phi", [](
KinematicResponse* instance) {
1450 std::vector<KDL::Frame> vec;
1451 for (
unsigned int i = 0; i < instance->
Phi.cols(); ++i)
1452 vec.push_back(instance->
Phi(i));
1456 py::enum_<Integrator>(module,
"Integrator")
1457 .value(
"RK1", Integrator::RK1)
1458 .value(
"SymplecticEuler", Integrator::SymplecticEuler)
1459 .value(
"RK2", Integrator::RK2)
1460 .value(
"RK4", Integrator::RK4)
1463 py::class_<DynamicsSolver, std::shared_ptr<DynamicsSolver>,
Object>(module,
"DynamicsSolver")
1498 py::class_<shapes::Shape, shapes::ShapePtr>(module,
"Shape")
1505 py::class_<shapes::Sphere, shapes::Shape, std::shared_ptr<shapes::Sphere>>(module,
"Sphere")
1507 .def(py::init<double>(), py::arg(
"radius"))
1511 py::class_<shapes::Cylinder, shapes::Shape, std::shared_ptr<shapes::Cylinder>>(module,
"Cylinder")
1513 .def(py::init<double, double>(), py::arg(
"radius"), py::arg(
"length"))
1518 py::class_<shapes::Cone, shapes::Shape, std::shared_ptr<shapes::Cone>>(module,
"Cone")
1520 .def(py::init<double, double>(), py::arg(
"radius"), py::arg(
"length"))
1525 py::class_<shapes::Box, shapes::Shape, std::shared_ptr<shapes::Box>>(module,
"Box")
1527 .def(py::init<double, double, double>(), py::arg(
"x"), py::arg(
"y"), py::arg(
"z"))
1530 py::class_<shapes::Plane, shapes::Shape, std::shared_ptr<shapes::Plane>>(module,
"Plane")
1532 .def(py::init<double, double, double, double>())
1540 py::class_<shapes::Mesh, shapes::Shape, std::shared_ptr<shapes::Mesh>>(module,
"Mesh")
1542 .def(py::init<unsigned int, unsigned int>())
1549 .def_property_readonly(
"triangles", [](
shapes::Mesh* instance) {
return Eigen::Map<const Eigen::Matrix<unsigned int, Eigen::Dynamic, 1>>(instance->
triangles, instance->
triangle_count); })
1552 .def_static(
"createMeshFromResource", [](
const std::string& resource) {
1555 py::arg(
"resource_path"), py::return_value_policy::take_ownership)
1559 py::arg(
"vertices"), py::return_value_policy::take_ownership)
1560 .def_static(
"createMeshFromVertices", [](
const EigenSTL::vector_Vector3d& vertices,
const std::vector<unsigned int>& triangles) {
1563 py::arg(
"vertices"), py::arg(
"triangles"), py::return_value_policy::take_ownership);
1565 py::class_<shapes::OcTree, shapes::Shape, std::shared_ptr<shapes::OcTree>>(module,
"OcTree")
1567 .def(py::init<
const std::shared_ptr<const octomap::OcTree>&>());
1569 py::enum_<shapes::ShapeType>(module,
"ShapeType")
1570 .value(
"UNKNOWN_SHAPE", shapes::ShapeType::UNKNOWN_SHAPE)
1571 .value(
"SPHERE", shapes::ShapeType::SPHERE)
1572 .value(
"CYLINDER", shapes::ShapeType::CYLINDER)
1573 .value(
"CONE", shapes::ShapeType::CONE)
1574 .value(
"BOX", shapes::ShapeType::BOX)
1575 .value(
"PLANE", shapes::ShapeType::PLANE)
1576 .value(
"MESH", shapes::ShapeType::MESH)
1577 .value(
"OCTREE", shapes::ShapeType::OCTREE)
1580 py::enum_<ArgumentPosition>(module,
"ArgumentPosition")
1581 .value(
"ARG0", ArgumentPosition::ARG0)
1582 .value(
"ARG1", ArgumentPosition::ARG1)
1583 .value(
"ARG2", ArgumentPosition::ARG2)
1584 .value(
"ARG3", ArgumentPosition::ARG3)
1585 .value(
"ARG4", ArgumentPosition::ARG4)
1591 py::class_<BoxQPSolution>(module,
"BoxQPSolution")
1597 module.def(
"box_qp",
1598 (
BoxQPSolution(*)(
const Eigen::MatrixXd& H,
const Eigen::VectorXd& q,
1599 const Eigen::VectorXd& b_low,
const Eigen::VectorXd& b_high,
1600 const Eigen::VectorXd& x_init,
const double gamma,
1601 const int max_iterations,
const double epsilon,
const double lambda,
1602 bool use_polynomial_linesearch,
1603 bool use_cholesky_factorization)) &
1605 py::arg(
"H"), py::arg(
"q"), py::arg(
"b_low"), py::arg(
"b_high"), py::arg(
"x_init"), py::arg(
"gamma"), py::arg(
"max_iterations"), py::arg(
"epsilon"), py::arg(
"lambda"), py::arg(
"use_polynomial_linesearch") =
true, py::arg(
"use_cholesky_factorization") =
true);
1607 module.def(
"box_qp_old",
1608 (
BoxQPSolution(*)(
const Eigen::MatrixXd& H,
const Eigen::VectorXd& q,
1609 const Eigen::VectorXd& b_low,
const Eigen::VectorXd& b_high,
1610 const Eigen::VectorXd& x_init,
const double gamma,
1611 const int max_iterations,
const double epsilon,
const double lambda,
1612 bool use_polynomial_linesearch,
1613 bool use_cholesky_factorization)) &
1615 py::arg(
"H"), py::arg(
"q"), py::arg(
"b_low"), py::arg(
"b_high"), py::arg(
"x_init"), py::arg(
"gamma"), py::arg(
"max_iterations"), py::arg(
"epsilon"), py::arg(
"lambda"), py::arg(
"use_polynomial_linesearch") =
false, py::arg(
"use_cholesky_factorization") =
false);
1619 auto cleanup_exotica = []() {
1623 module.add_object(
"_cleanup", py::capsule(cleanup_exotica));