Skip to content

Commit 80f4f53

Browse files
committed
[C++] Update bindings of Angle Axis
- Update API to follow Eigen conventions - Add Doc - Remove unaligned conversions
1 parent c7fdc96 commit 80f4f53

File tree

1 file changed

+68
-88
lines changed

1 file changed

+68
-88
lines changed

src/angle-axis.hpp

Lines changed: 68 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -23,119 +23,99 @@
2323

2424
namespace eigenpy
2525
{
26-
template<>
27-
struct UnalignedEquivalent<Eigen::AngleAxisd>
28-
{
29-
typedef Eigen::AngleAxis<double> type;
30-
};
3126

3227
namespace bp = boost::python;
3328

34-
template<typename D>
29+
template<typename AngleAxis>
3530
class AngleAxisVisitor
36-
: public boost::python::def_visitor< AngleAxisVisitor<D> >
31+
: public boost::python::def_visitor< AngleAxisVisitor<AngleAxis> >
3732
{
38-
typedef D AngleAxis;
39-
typedef typename eigenpy::UnalignedEquivalent<D>::type AngleAxisUnaligned;
40-
41-
typedef typename AngleAxisUnaligned::Scalar Scalar;
42-
typedef typename eigenpy::UnalignedEquivalent<typename AngleAxisUnaligned::Vector3>::type Vector3;
43-
typedef typename eigenpy::UnalignedEquivalent<typename AngleAxisUnaligned::Matrix3>::type Matrix3;
44-
45-
typedef eigenpy::UnalignedEquivalent<Eigen::Quaternion<Scalar> > Quaternion;
4633

34+
typedef typename AngleAxis::Scalar Scalar;
35+
typedef typename AngleAxis::Vector3 Vector3;
36+
typedef typename AngleAxis::Matrix3 Matrix3;
37+
38+
typedef typename Eigen::Quaternion<Scalar,0> Quaternion;
39+
4740
public:
4841

4942
template<class PyClass>
5043
void visit(PyClass& cl) const
5144
{
5245
cl
53-
.def(bp::init<Scalar,Vector3>
54-
((bp::arg("angle"),bp::arg("axis")),
55-
"Initialize from angle and axis"))
56-
.def(bp::init<Matrix3>
57-
((bp::arg("rotationMatrix")),
58-
"Initialize from a rotation matrix"))
59-
.def("__init__",bp::make_constructor(&AngleAxisVisitor::constructFromQuaternion,
60-
bp::default_call_policies(),
61-
(bp::arg("quaternion"))),"Initialize from quaternion")
62-
.def(bp::init<AngleAxisUnaligned>((bp::arg("clone"))))
63-
64-
.def("matrix",&AngleAxisUnaligned::toRotationMatrix,"Return the corresponding rotation matrix 3x3.")
65-
.def("vector",&AngleAxisVisitor::toVector3,"Return the correspond angle*axis vector3")
66-
.add_property("axis",&AngleAxisVisitor::getAxis,&AngleAxisVisitor::setAxis)
67-
.add_property("angle",&AngleAxisVisitor::getAngle,&AngleAxisVisitor::setAngle)
68-
69-
/* --- Methods --- */
70-
.def("normalize",&AngleAxisVisitor::normalize,"Normalize the axis vector (without changing the angle).")
71-
.def("inverse",&AngleAxisUnaligned::inverse,"Return the inverse rotation.")
72-
.def("apply",&AngleAxisVisitor::apply,(bp::arg("vector3")),"Apply the rotation map to the vector")
73-
74-
/* --- Operators --- */
75-
.def(bp::self * bp::other<Vector3>())
76-
.def("__eq__",&AngleAxisVisitor::__eq__)
77-
.def("__ne__",&AngleAxisVisitor::__ne__)
78-
.def("__abs__",&AngleAxisVisitor::getAngleAbs)
79-
;
46+
.def(bp::init<>("Default constructor"))
47+
.def(bp::init<Scalar,Vector3>
48+
((bp::arg("angle"),bp::arg("axis")),
49+
"Initialize from angle and axis."))
50+
.def(bp::init<Matrix3>
51+
((bp::arg("rotationMatrix")),
52+
"Initialize from a rotation matrix"))
53+
.def(bp::init<Quaternion>(bp::arg("quaternion"),"Initialize from a quaternion."))
54+
.def(bp::init<AngleAxis>(bp::arg("copy"),"Copy constructor."))
55+
56+
/* --- Properties --- */
57+
.add_property("axis",
58+
bp::make_function((const Vector3 & (AngleAxis::*)()const)&AngleAxis::axis,
59+
bp::return_value_policy<bp::copy_const_reference>()),
60+
&AngleAxisVisitor::setAxis,"The rotation axis.")
61+
.add_property("angle",
62+
(Scalar (AngleAxis::*)()const)&AngleAxis::angle,
63+
&AngleAxisVisitor::setAngle,"The rotation angle.")
64+
65+
/* --- Methods --- */
66+
.def("inverse",&AngleAxis::inverse,"Return the inverse rotation.")
67+
.def("fromRotationMatrix",&AngleAxis::template fromRotationMatrix<Matrix3>,
68+
bp::arg("Sets *this from a 3x3 rotation matrix."),bp::return_self<>())
69+
.def("toRotationMatrix",&AngleAxis::toRotationMatrix,"Constructs and returns an equivalent 3x3 rotation matrix.")
70+
.def("matrix",&AngleAxis::matrix,"Returns an equivalent rotation matrix.")
71+
.def("isApprox",(bool (AngleAxis::*)(const AngleAxis &))&AngleAxis::isApprox,
72+
"Returns true if *this is approximately equal to other.")
73+
.def("isApprox",(bool (AngleAxis::*)(const AngleAxis &, const Scalar prec))&AngleAxis::isApprox,
74+
bp::args("other","prec"),
75+
"Returns true if *this is approximately equal to other, within the precision determined by prec.")
76+
77+
/* --- Operators --- */
78+
.def(bp::self * bp::other<Vector3>())
79+
.def(bp::self * bp::other<Quaternion>())
80+
.def(bp::self * bp::self)
81+
.def("__eq__",&AngleAxisVisitor::__eq__)
82+
.def("__ne__",&AngleAxisVisitor::__ne__)
83+
84+
.def("__str__",&print)
85+
.def("__repr__",&print)
86+
;
8087
}
88+
8189
private:
82-
83-
static AngleAxisUnaligned* constructFromQuaternion(const Eigen::Quaternion<Scalar,Eigen::DontAlign> & qu)
84-
{
85-
Eigen::Quaternion<Scalar> q = qu;
86-
return new AngleAxisUnaligned(q);
87-
}
88-
89-
static Vector3 apply(const AngleAxisUnaligned & r, const Vector3 & v ) { return r*v; }
9090

91-
static Vector3 getAxis(const AngleAxisUnaligned& self) { return self.axis(); }
92-
static void setAxis(AngleAxisUnaligned& self, const Vector3 & r)
93-
{
94-
self = AngleAxisUnaligned( self.angle(),r );
95-
}
91+
static void setAxis(AngleAxis & self, const Vector3 & axis)
92+
{ self.axis() = axis; }
9693

97-
static double getAngle(const AngleAxisUnaligned& self) { return self.angle(); }
98-
static void setAngle( AngleAxisUnaligned& self, const double & th)
99-
{
100-
self = AngleAxisUnaligned( th,self.axis() );
101-
}
102-
static double getAngleAbs(const AngleAxisUnaligned& self) { return std::abs(self.angle()); }
94+
static void setAngle( AngleAxis & self, const Scalar & angle)
95+
{ self.angle() = angle; }
10396

104-
static bool __eq__(const AngleAxisUnaligned & u, const AngleAxisUnaligned & v)
105-
{
106-
return u.isApprox(v);
107-
}
108-
static bool __ne__(const AngleAxisUnaligned & u, const AngleAxisUnaligned & v)
109-
{
110-
return !__eq__(u,v);
111-
}
97+
static bool __eq__(const AngleAxis & u, const AngleAxis & v)
98+
{ return u.isApprox(v); }
99+
static bool __ne__(const AngleAxis & u, const AngleAxis & v)
100+
{ return !__eq__(u,v); }
112101

113-
static Vector3 toVector3( const AngleAxisUnaligned & self ) { return self.axis()*self.angle(); }
114-
static void normalize( AngleAxisUnaligned & self )
102+
static std::string print(const AngleAxis & self)
115103
{
116-
setAxis(self,self.axis() / self.axis().norm());
117-
}
118-
119-
private:
120-
121-
static PyObject* convert(AngleAxis const& q)
122-
{
123-
AngleAxisUnaligned qx = q;
124-
return boost::python::incref(boost::python::object(qx).ptr());
104+
std::stringstream ss;
105+
ss << "angle: " << self.angle() << std::endl;
106+
ss << "axis: " << self.axis().transpose() << std::endl;
107+
108+
return ss.str();
125109
}
126110

127111
public:
128112

129113
static void expose()
130114
{
131-
bp::class_<AngleAxisUnaligned>("AngleAxis",
132-
"AngleAxis representation of rotations.\n\n",
133-
bp::init<>())
134-
.def(AngleAxisVisitor<D>());
135-
136-
// TODO: check the problem of fix-size Angle Axis.
137-
//bp::to_python_converter< AngleAxis,AngleAxisVisitor<D> >();
138-
115+
bp::class_<AngleAxis>("AngleAxis",
116+
"AngleAxis representation of rotations.\n\n",
117+
bp::no_init)
118+
.def(AngleAxisVisitor<AngleAxis>());
139119
}
140120

141121
};

0 commit comments

Comments
 (0)