Python bindings for the Lie++ C++ library, providing efficient operations on Lie groups commonly used in robotics and computer vision.
- SO(3): 3D rotation group
- SE(3): Special Euclidean group (pose: rotation + translation)
- SE_2(3): Extended Special Euclidean group (pose + velocity)
- NumPy integration for seamless array operations
- High-performance C++ implementation with Python convenience
- Comprehensive test suite and examples
git clone https://github.com/Swarm-Systems-Lab/lieplusplus_py.git
cd lieplusplus_py
pip install -e .Alternatively, for a development installation (includes testing and formatting tools):
pip install -e .[dev]- Python 3.8+
- NumPy
- pybind11
- C++17 compatible compiler
- Eigen3 (automatically downloaded during the build)
import numpy as np
from lieplusplus import SO3
# --- Constructors ---
R = SO3() # Identity rotation
R = SO3([1, 0, 0, 0]) # Quaternion [w, x, y, z]
R = SO3(np.eye(3)) # Rotation matrix (3×3)
R = SO3([0.1, 0.2, 0.3]) # Rotation vector (exp map)
R = SO3([1, 0, 0], [0, 1, 0]) # Rotation sending u → v
R = SO3.random() # Random rotation
# --- Group operations ---
R3 = R1 * R2 # Compose rotations
v_rot = R * v # Rotate a 3-vector
M_rot = R * M # Rotate a 3×3 matrix
# --- Lie-theoretic operations (static) ---
u = SO3.log(R) # R^3 log-coordinate
R2 = SO3.exp(u) # Exponential map
U = SO3.wedge(u) # 3×3 skew-symmetric matrix
u2 = SO3.vee(U) # Vector from skew matrix
u0 = SO3.tangent_zero() # Zero element of so(3)
# --- Jacobians ---
J = SO3.leftJacobian(u)
Jinv = SO3.invLeftJacobian(u)
# --- Accessors ---
R.asMatrix() # 3×3 rotation matrix
R.Adjoint() # 3×3 Adjoint matrix
R.inv() # Inverse rotation
R.q() # Quaternion [w, x, y, z]import numpy as np
from lieplusplus import SE3, SO3
# --- Constructors ---
T = SE3() # Identity pose
T = SE3(R, t) # SO(3) + translation vector
T = SE3(np.eye(4)) # Full 4×4 pose matrix
T = SE3([0.1, 0.2, 0.3], [1, 2, 3]) # Rotation vector + translation
T = SE3.random() # Random pose
# --- Group operations ---
T3 = T1 * T2 # Compose poses
p_world = T * p # Transform a 3D point
# --- Lie-theoretic operations (static) ---
u = SE3.log(T) # R^6 tangent vector
T2 = SE3.exp(u)
U = SE3.wedge(u)
u2 = SE3.vee(U)
u0 = SE3.tangent_zero()
# --- Accessors ---
T.asMatrix() # 4×4 transformation matrix
T.Adjoint() # 6×6 Adjoint matrix
T.inv() # Inverse pose
T.R() # Rotation (SO3)
T.q() # Quaternion
T.translation() # 3D translation vectorimport numpy as np
from lieplusplus import SE3_2, SO3
# --- Constructors ---
X = SE3_2() # Identity extended pose
X = SE3_2(R, [v, p]) # Rotation + [velocity, position]
X = SE3_2(R, [np.zeros(3), np.ones(3)]) # Example
X = SE3_2.random() # Random extended pose
# --- Group operations ---
X3 = X1 * X2
# --- Lie-theoretic operations (static) ---
u = SE3_2.log(X) # R^9 tangent vector
X2 = SE3_2.exp(u)
U = SE3_2.wedge(u)
u2 = SE3_2.vee(U)
u0 = SE3_2.tangent_zero()
# --- Accessors ---
X.asMatrix() # 5×5 extended matrix
X.Adjoint() # 9×9 Adjoint matrix
X.inv() # Inverse extended pose
X.R() # Rotation (SO3)
X.v() # Velocity vector
X.p() # Position vector