ethz-asl / cuckoo_time_translator

algorithms for synchronizing clocks
Other
89 stars 22 forks source link

Python bindings for overloaded SwitchingOwt public methods. #40

Closed rikba closed 6 years ago

rikba commented 6 years ago

We would like to access the current OWT to get information about the current offset and skew estimation https://github.com/ethz-asl/leica_totalstation_interface/pull/18. When adding getCurrentOwt() to the python bindings, i.e.,

  class_<SwitchingOwt, bases<OneWayTranslator>, boost::noncopyable>("SwitchingOwt", init<double, const OneWayTranslator &>())
    .def("getSwitchingTimeSeconds", &SwitchingOwt::getSwitchingTimeSeconds, "double getSwitchingTimeSeconds() const")
    .def("getCurrentOwt", &SwitchingOwt::getCurrentOwt, "const OneWayTranslator& getCurrentOwt() const")
    ;

we get the error:

Errors     << cuckoo_time_translator_python:make /home/rikba/catkin_ws/logs/cuckoo_time_translator_python/build.make.020.log                                                                                                                                                  
/home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp: In function ‘void exportTimestampOwts()’:
/home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:63:104: error: no matching function for call to ‘boost::python::class_<cuckoo_time_translator::SwitchingOwt, boost::python::bases<cuckoo_time_translator::OneWayTranslator>, boost::noncopyable_::noncopyable>::def(const char [14], <unresolved overloaded function type>, const char [46])’
     .def("getCurrentOwt", &SwitchingOwt::getCurrentOwt, "const OneWayTranslator& getCurrentOwt() const")
                                                                                                        ^
In file included from /usr/include/boost/python.hpp:18:0,
                 from /home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:1:
/usr/include/boost/python/class.hpp:224:11: note: candidate: template<class Derived> boost::python::class_<T, X1, X2, X3>::self& boost::python::class_<T, X1, X2, X3>::def(const boost::python::def_visitor<Derived>&) [with Derived = Derived; W = cuckoo_time_translator::SwitchingOwt; X1 = boost::python::bases<cuckoo_time_translator::OneWayTranslator>; X2 = boost::noncopyable_::noncopyable; X3 = boost::python::detail::not_specified]
     self& def(def_visitor<Derived> const& visitor)
           ^
/usr/include/boost/python/class.hpp:224:11: note:   template argument deduction/substitution failed:
/home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:63:104: note:   mismatched types ‘const boost::python::def_visitor<U>’ and ‘const char [14]’
     .def("getCurrentOwt", &SwitchingOwt::getCurrentOwt, "const OneWayTranslator& getCurrentOwt() const")
                                                                                                        ^
In file included from /usr/include/boost/python.hpp:18:0,
                 from /home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:1:
/usr/include/boost/python/class.hpp:234:11: note: candidate: template<class F> boost::python::class_<T, X1, X2, X3>::self& boost::python::class_<T, X1, X2, X3>::def(const char*, F) [with F = F; W = cuckoo_time_translator::SwitchingOwt; X1 = boost::python::bases<cuckoo_time_translator::OneWayTranslator>; X2 = boost::noncopyable_::noncopyable; X3 = boost::python::detail::not_specified]
     self& def(char const* name, F f)
           ^
/usr/include/boost/python/class.hpp:234:11: note:   template argument deduction/substitution failed:
/home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:63:104: note:   candidate expects 2 arguments, 3 provided
     .def("getCurrentOwt", &SwitchingOwt::getCurrentOwt, "const OneWayTranslator& getCurrentOwt() const")
                                                                                                        ^
In file included from /usr/include/boost/python.hpp:18:0,
                 from /home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:1:
/usr/include/boost/python/class.hpp:243:11: note: candidate: template<class A1, class A2> boost::python::class_<T, X1, X2, X3>::self& boost::python::class_<T, X1, X2, X3>::def(const char*, A1, const A2&) [with A1 = A1; A2 = A2; W = cuckoo_time_translator::SwitchingOwt; X1 = boost::python::bases<cuckoo_time_translator::OneWayTranslator>; X2 = boost::noncopyable_::noncopyable; X3 = boost::python::detail::not_specified]
     self& def(char const* name, A1 a1, A2 const& a2)
           ^
/usr/include/boost/python/class.hpp:243:11: note:   template argument deduction/substitution failed:
/home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:63:104: note:   couldn't deduce template parameter ‘A1’
     .def("getCurrentOwt", &SwitchingOwt::getCurrentOwt, "const OneWayTranslator& getCurrentOwt() const")
                                                                                                        ^
In file included from /usr/include/boost/python.hpp:18:0,
                 from /home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:1:
/usr/include/boost/python/class.hpp:250:11: note: candidate: template<class Fn, class A1, class A2> boost::python::class_<T, X1, X2, X3>::self& boost::python::class_<T, X1, X2, X3>::def(const char*, Fn, const A1&, const A2&) [with Fn = Fn; A1 = A1; A2 = A2; W = cuckoo_time_translator::SwitchingOwt; X1 = boost::python::bases<cuckoo_time_translator::OneWayTranslator>; X2 = boost::noncopyable_::noncopyable; X3 = boost::python::detail::not_specified]
     self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2)
           ^
/usr/include/boost/python/class.hpp:250:11: note:   template argument deduction/substitution failed:
/home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:63:104: note:   candidate expects 4 arguments, 3 provided
     .def("getCurrentOwt", &SwitchingOwt::getCurrentOwt, "const OneWayTranslator& getCurrentOwt() const")
                                                                                                        ^
In file included from /usr/include/boost/python.hpp:18:0,
                 from /home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:1:
/usr/include/boost/python/class.hpp:266:11: note: candidate: template<class Fn, class A1, class A2, class A3> boost::python::class_<T, X1, X2, X3>::self& boost::python::class_<T, X1, X2, X3>::def(const char*, Fn, const A1&, const A2&, const A3&) [with Fn = Fn; A1 = A1; A2 = A2; A3 = A3; W = cuckoo_time_translator::SwitchingOwt; X1 = boost::python::bases<cuckoo_time_translator::OneWayTranslator>; X2 = boost::noncopyable_::noncopyable; X3 = boost::python::detail::not_specified]
     self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3)
           ^
/usr/include/boost/python/class.hpp:266:11: note:   template argument deduction/substitution failed:
/home/rikba/catkin_ws/src/cuckoo_time_translator/cuckoo_time_translator_python/src/module.cpp:63:104: note:   candidate expects 5 arguments, 3 provided
     .def("getCurrentOwt", &SwitchingOwt::getCurrentOwt, "const OneWayTranslator& getCurrentOwt() const")
                                                                                                        ^
make[2]: *** [CMakeFiles/cuckoo_time_translator_python.dir/src/module.cpp.o] Error 1
make[1]: *** [CMakeFiles/cuckoo_time_translator_python.dir/all] Error 2
make: *** [all] Error 2

I assume this is related to python not having function overloads. Others suggest creating an intermediate class to interface the code in python. Any suggestions @HannesSommer ?

rikba commented 6 years ago

Or is this even necessary to access getOffset() and getSkew() from time_translator = SwitchingOwt(3600, ConvexHullOwt())?

HannesSommer commented 6 years ago

Oh sorry, yes I've overlooked that problem. It is necessary and even requires a cast to ConvexHullOwt because that type gets lost on the way. Yes, the const overload should be the problem. The correct way is to do static casting to the expected function type to pick the overload. Something like

static_cast<OneWayTranslator & (SwitchingOwt::*)()>(&SwitchingOwt::getCurrentOwt)

should do the trick.

HannesSommer commented 6 years ago

Also, there is the issue of lifetime of the object referenced by the returned reference. I'd suggest using the non const method (like in my example above) and add the , return_internal_reference<>() argument to the .def call, like here.

I can also do that soon.