diff --git a/.github/workflows/ros_ci.yml b/.github/workflows/ros_ci.yml index ff06681c302c473a015c58ae66c82db92a276a9d..6d7e13a7df488e98394b2b9c9c59105c7c2a3f52 100644 --- a/.github/workflows/ros_ci.yml +++ b/.github/workflows/ros_ci.yml @@ -12,10 +12,13 @@ jobs: matrix: env: - {ROS_DISTRO: melodic} - - {ROS_DISTRO: noetic} + - {ROS_DISTRO: noetic, BUILDER: catkin_tools} + - {ROS_DISTRO: foxy} + - {ROS_DISTRO: galactic} + - {ROS_DISTRO: foxy, PRERELEASE: true} + - {ROS_DISTRO: galactic, PRERELEASE: true} env: CCACHE_DIR: /github/home/.ccache # Enable ccache - BUILDER: catkin_tools runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 765d2abf15d3488b895c288cf23d7ab69ad1e21d..95632c47321b8561ebfc6d78a209a1894d7454a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,6 +230,9 @@ ADD_SOURCE_GROUP(${PROJECT_NAME}_SOURCES) # Install package for ROS install(FILES package.xml DESTINATION share/eigenpy) +# Allows Colcon to find non-Ament packages when using workspace underlays +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/share/ament_index/resource_index/packages/${PROJECT_NAME} "") +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/ament_index/resource_index/packages/${PROJECT_NAME} DESTINATION share/ament_index/resource_index/packages) # ---------------------------------------------------- # --- PYTHON LIBRARY --------------------------------- diff --git a/cmake b/cmake index b0aa0ff9377c953340aeb037297003df04d6185f..b0a77e2ead3f8dbb201b05e42048bb1cfc6a518e 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit b0aa0ff9377c953340aeb037297003df04d6185f +Subproject commit b0a77e2ead3f8dbb201b05e42048bb1cfc6a518e diff --git a/include/eigenpy/quaternion.hpp b/include/eigenpy/quaternion.hpp index 1f824eced7d5beafa4ff044ebb8e978fc3fedc7a..7e00edfa3bc5b6602d4710270ec0bd17d2a77cdf 100644 --- a/include/eigenpy/quaternion.hpp +++ b/include/eigenpy/quaternion.hpp @@ -275,7 +275,7 @@ namespace eigenpy return new Quaternion; } - static Quaternion* FromOneVector(const Vector4& v) + static Quaternion* FromOneVector(const Eigen::Ref<Vector4> v) { Quaternion* q(new Quaternion(v[3],v[0],v[1],v[2])); return q; diff --git a/include/eigenpy/user-type.hpp b/include/eigenpy/user-type.hpp index ed49ceb21fc10c72b29dd31ea015f6c1f1719fe1..cbe0c05d285ad0dd972f6c28b3fb4035582c3de9 100644 --- a/include/eigenpy/user-type.hpp +++ b/include/eigenpy/user-type.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2020-2021 INRIA +// Copyright (c) 2020-2022 INRIA // #ifndef __eigenpy_user_type_hpp__ @@ -19,14 +19,18 @@ namespace eigenpy { static To run(const From & from) { - return (To)from; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wfloat-conversion" + return static_cast<To>(from); +#pragma GCC diagnostic pop } - + }; namespace internal { - + template<typename From, typename To> static void cast(void * from_, void * to_, npy_intp n, void * /*fromarr*/, void * /*toarr*/) { @@ -38,7 +42,7 @@ namespace eigenpy to[i] = eigenpy::cast<From,To>::run(from[i]); } } - + template<typename T, int type_code = NumpyEquivalentType<T>::type_code> struct SpecialMethods { @@ -54,7 +58,7 @@ namespace eigenpy inline static int fillwithscalar(void* buffer_, npy_intp length, void* value, void* arr); }; - + template<typename T> struct OffsetOf { @@ -63,10 +67,10 @@ namespace eigenpy char c; T v; }; - + enum { value = offsetof(Data, v) }; }; - + template<typename T> struct SpecialMethods<T,NPY_USERDEF> { @@ -79,7 +83,7 @@ namespace eigenpy T & t2 = *static_cast<T*>(src); t1 = t2; } - + if(swap) { T & t1 = *static_cast<T*>(dst); @@ -112,14 +116,14 @@ namespace eigenpy /// pointed to by data. This function deals with “misbehaved†arrays. /// If successful, a zero is returned, otherwise, a negative one is returned /// (and a Python error set). - + /// \param[in] src_obj Pointer to the location of the python object /// \param[in] dest_ptr Pointer to the location in the array where the source object should be saved. /// \param[in] array Pointer to the location of the array /// /// \returns int Success(0) or Failure(-1) /// - + inline static int setitem(PyObject * src_obj, void * dest_ptr, void * array) { // std::cout << "setitem" << std::endl; @@ -132,7 +136,7 @@ namespace eigenpy PyArray_Descr * descr = PyArray_DTYPE(py_array); PyTypeObject * array_scalar_type = descr->typeobj; PyTypeObject * src_obj_type = Py_TYPE(src_obj); - + if(array_scalar_type != src_obj_type) { std::stringstream ss; @@ -141,7 +145,7 @@ namespace eigenpy eigenpy::Exception(ss.str()); return -1; } - + bp::extract<T&> extract_src_obj(src_obj); if(!extract_src_obj.check()) { @@ -151,25 +155,25 @@ namespace eigenpy eigenpy::Exception(ss.str()); return -1; } - + const T & src = extract_src_obj(); T & dest = *static_cast<T*>(dest_ptr); dest = src; return 0; } - + inline static void copyswapn(void * dst, long dstride, void * src, long sstride, long n, int swap, void * array) { // std::cout << "copyswapn" << std::endl; - + char *dstptr = static_cast<char*>(dst); char *srcptr = static_cast<char*>(src); - + PyArrayObject * py_array = static_cast<PyArrayObject *>(array); PyArray_CopySwapFunc * copyswap = PyArray_DESCR(py_array)->f->copyswap; - + for (npy_intp i = 0; i < n; i++) { copyswap(dstptr, srcptr, swap, array); @@ -177,7 +181,7 @@ namespace eigenpy srcptr += sstride; } } - + inline static npy_bool nonzero(void * ip, void * array) { // std::cout << "nonzero" << std::endl; @@ -196,7 +200,7 @@ namespace eigenpy return (npy_bool)(tmp_value != ZeroValue); } } - + inline static void dotfunc(void * ip0_, npy_intp is0, void * ip1_, npy_intp is1, void * op, npy_intp n, void * /*arr*/) { @@ -206,13 +210,13 @@ namespace eigenpy typedef const Eigen::Map<const VectorT,0,InputStride> ConstMapType; ConstMapType - v0(static_cast<T*>(ip0_),n,InputStride(is0/sizeof(T))), - v1(static_cast<T*>(ip1_),n,InputStride(is1/sizeof(T))); - + v0(static_cast<T*>(ip0_),n,InputStride(is0/(Eigen::DenseIndex)sizeof(T))), + v1(static_cast<T*>(ip1_),n,InputStride(is1/(Eigen::DenseIndex)sizeof(T))); + *static_cast<T*>(op) = v0.dot(v1); } - - + + inline static int fillwithscalar(void* buffer_, npy_intp length, void* value, void* /*arr*/) { @@ -225,8 +229,8 @@ namespace eigenpy } return 0; } - - + + static int fill(void* data_, npy_intp length, void* /*arr*/) { // std::cout << "fillwithscalar" << std::endl; @@ -240,10 +244,10 @@ namespace eigenpy } return 0; } - + }; // struct SpecialMethods<T,NPY_USERDEF> - + } // namespace internal @@ -252,17 +256,17 @@ namespace eigenpy { PyArray_Descr* from_array_descr = Register::getPyArrayDescr<From>(); // int from_typenum = Register::getTypeCode<From>(); - + // PyTypeObject * to_py_type = Register::getPyType<To>(); int to_typenum = Register::getTypeCode<To>(); assert(to_typenum >= 0 && "to_typenum is not valid"); assert(from_array_descr != NULL && "from_array_descr is not valid"); - + std::cout << "From: " << bp::type_info(typeid(From)).name() << " " << Register::getTypeCode<From>() << " to: " << bp::type_info(typeid(To)).name() << " " << Register::getTypeCode<To>() << "\n to_typenum: " << to_typenum << std::endl; - + if(call_PyArray_RegisterCastFunc(from_array_descr, to_typenum, static_cast<PyArray_VectorUnaryFunc *>(&eigenpy::internal::cast<From,To>)) < 0) @@ -277,7 +281,7 @@ namespace eigenpy eigenpy::Exception(ss.str()); return false; } - + if (safe && call_PyArray_RegisterCanCast(from_array_descr, to_typenum, NPY_NOSCALAR) < 0) @@ -292,7 +296,7 @@ namespace eigenpy eigenpy::Exception(ss.str()); return false; } - + return true; } @@ -307,17 +311,17 @@ namespace eigenpy bp::type_info type = bp::type_id<T>(); const bp::converter::registration* registration = bp::converter::registry::query(type); - + // If the class is not registered, return None. if (!registration) { //std::cerr<<"Class Not Registered. Returning Empty."<<std::endl; return bp::object(); } - + bp::handle<PyTypeObject> handle(bp::borrowed(registration->get_class_object())); return bp::object(handle); } - + template<typename Scalar> int registerNewType(PyTypeObject * py_type_ptr = NULL) { @@ -325,16 +329,16 @@ namespace eigenpy // In this case, the registration is not required. if(isNumpyNativeType<Scalar>()) return NumpyEquivalentType<Scalar>::type_code; - + // Retrieve the registered type for the current Scalar if(py_type_ptr == NULL) { // retrive the type from Boost.Python py_type_ptr = Register::getPyType<Scalar>(); } - + if(Register::isRegistered(py_type_ptr)) return Register::getTypeCode(py_type_ptr); // the type is already registered - + PyArray_GetItemFunc * getitem = &internal::SpecialMethods<Scalar>::getitem; PyArray_SetItemFunc * setitem = &internal::SpecialMethods<Scalar>::setitem; PyArray_NonzeroFunc * nonzero = &internal::SpecialMethods<Scalar>::nonzero; @@ -343,7 +347,7 @@ namespace eigenpy PyArray_DotFunc * dotfunc = &internal::SpecialMethods<Scalar>::dotfunc; PyArray_FillFunc * fill = &internal::SpecialMethods<Scalar>::fill; PyArray_FillWithScalarFunc * fillwithscalar = &internal::SpecialMethods<Scalar>::fillwithscalar; - + int code = Register::registerNewType(py_type_ptr, &typeid(Scalar), sizeof(Scalar), @@ -353,13 +357,13 @@ namespace eigenpy dotfunc, fill, fillwithscalar); - + call_PyArray_RegisterCanCast(call_PyArray_DescrFromType(NPY_OBJECT), code, NPY_NOSCALAR); - + return code; } - + } // namespace eigenpy #endif // __eigenpy_user_type_hpp__ diff --git a/package.xml b/package.xml index 8454baff87311951e4f7809b31de02037091646a..13171594d921949b16ce2db2cb2362484113df6a 100644 --- a/package.xml +++ b/package.xml @@ -13,9 +13,10 @@ <build_depend>git</build_depend> <build_depend>doxygen</build_depend> - <!-- The following tags are recommended by REP-136 --> + + <!-- The following tag is recommended by REP-136 --> <exec_depend condition="$ROS_VERSION == 1">catkin</exec_depend> - <exec_depend condition="$ROS_VERSION == 2">ament_cmake</exec_depend> + <depend condition="$ROS_PYTHON_VERSION == 2">python</depend> <depend condition="$ROS_PYTHON_VERSION == 3">python3</depend> <depend condition="$ROS_PYTHON_VERSION == 2">python-numpy</depend>