update doc of several classes

This commit is contained in:
Brian Delhaisse
2019-04-14 19:19:11 +02:00
parent ab9a3e18a1
commit c3d54f6c53
7 changed files with 178 additions and 80 deletions
@@ -1,5 +1,5 @@
#!/usr/bin/env python
r"""Provide the various constraints used in QP.
r"""Provide the various constraints and bounds used in QP.
Provide the various optimization constraints (:math:`G, h, F, c` in the upcoming formulation) used in QP.
@@ -27,6 +27,7 @@ __status__ = "Development"
class DynamicConstraint(Constraint):
r"""Dynamic Constraints
Dynamic constraint using Equation of Motion (by using inertia and the non-linear terms).
"""
pass
@@ -57,8 +58,29 @@ class FrictionCones(DynamicConstraint):
pass
class FrictionPyramide(DynamicConstraint):
r"""Friction pyramide constraint (using contact force optimization)
"""
pass
class UnilateralContact(DynamicConstraint):
r"""Unilateral Contact constraint.
Mechanical constraint which prevents penetration between two bodies.
"""
class WrenchLimits(DynamicConstraint):
r"""Wrench Limits (using contact force optimization).
"""
pass
class ZMP(DynamicConstraint):
r"""ZMP constraint.
"""
pass
@@ -69,4 +69,12 @@ class JointVelocityLimits(KinematicConstraint):
class SelfCollisionAvoidance(KinematicConstraint):
r"""Self-collision avoidance constraint.
"""
"""
pass
class ConvexHull(Constraint):
r"""Convex Hull constraint
"""
pass
+23 -1
View File
@@ -34,6 +34,7 @@ class DynamicTask(Task):
class MinAcceleration(DynamicTask):
r"""Min acceleration task.
Minimize joint accelerations.
"""
pass
@@ -41,6 +42,7 @@ class MinAcceleration(DynamicTask):
class MinEffort(DynamicTask):
r"""Min effort task.
Minimize joint torques / forces.
"""
pass
@@ -60,7 +62,27 @@ class ForceManipulability(DynamicTask):
class CentroidalDynamics(DynamicTask):
r"""Centroidal dynamics task (u
r"""Centroidal dynamics task.
"""
pass
class LinearMomentum(DynamicTask):
r"""Linear Momentum task.
"""
pass
class AngularMomentum(DynamicTask):
r"""Angular Momentum Task.
"""
pass
class MinGroundReactionForce(DynamicTask):
r"""Min Ground Reaction Force task.
"""
pass
@@ -58,6 +58,34 @@ class Postural(KinematicTask):
While optimizing, the robot can get to weird configurations. This postural kinematic task tries to keep the
robot's kinematic configuration close to the given default joint positions. This task is usually put at the end of
the stack of tasks, once all the other tasks have been fulfilled.
The A matrix is the identity matrix, the variables being optimized are the joint velocities :math:`\dot{q}`, and
the :math:`b` vector is :math:`\dot{q}_d + K_q (q_d - q)`.
"""
pass
class CartesianPosition(KinematicTask):
r"""Cartesian position kinematic task.
The A matrix is the translational Jacobian matrix between the base (or world) and the specified link, the variables
being optimized are the joint velocities :math:`\dot{q}`, and the :math:`b` vector is
:math:`\dot{p}_d + K_p (p_d - p)`.
"""
pass
class CartesianOrientation(KinematicTask):
r"""Cartesian orientation kinematic task.
The A matrix is the rotational Jacobian matrix, the variables being optimized are the joint velocities
:math:`\dot{q}`, and the :math:`b` vector is :math:`\omega_d + K_o e_o` where
:math:`e_o = -(\eta_d \espilon - \eta \epsilon_d + [\epsilon_d \times] \epsilon)`. The :math:`\eta` and
:math:`\epsilon` are respectively the scalar and vector part of the quaternion.
The quaternion error :math:`\Delta Q` is given by :math:`Q_d * Q_e^{-1}`.
Once the optimal joint velocities :math:`\dot{q}^*` have been computed, they can be given to a velocity controller,
or a position controller using :math:`q = q + \dot{q}^* dt`, with :math:`dt` being the control loop period.
"""
pass
@@ -65,6 +93,7 @@ class Postural(KinematicTask):
class Cartesian(KinematicTask):
r"""Cartesian kinematic task
The Cartesian task is the aggregate of a Cartesian position task and a Cartesian orientation task.
"""
pass
@@ -72,6 +101,7 @@ class Cartesian(KinematicTask):
class CoM(KinematicTask):
r"""Center of Mass task
The Center of Mass is a specific Cartesian position task.
"""
pass
@@ -79,6 +109,10 @@ class CoM(KinematicTask):
class VelocityManipulability(KinematicTask):
r"""Velocity manipulability task
The A matrix is the identity matrix, the variables being optimized are the joint velocities :math:`\dot{q}`, and
the :math:`b` vector is 0.
This task is often used to avoid joint singularities and their neighborhood.
"""
pass
+87 -77
View File
@@ -879,7 +879,7 @@ class Robot(ControllableBody):
self.sim.set_joint_motor_control(self.id, joint_ids, self.sim.TORQUE_CONTROL, forces=torque)
def set_joint_motor_control(self, joint_ids, control_mode, **kwargs):
"""
r"""
Set joint motor control.
In position control:
@@ -1110,7 +1110,7 @@ class Robot(ControllableBody):
compute_forward_kinematics=compute_forward_kinematics)
def get_link_names(self, link_ids=None):
"""
r"""
Return the name of the given link(s).
Args:
@@ -1130,7 +1130,7 @@ class Robot(ControllableBody):
return [self.sim.get_joint_info(self.id, link)[12] for link in link_ids]
def get_link_masses(self, link_ids=None):
"""
r"""
Return the mass of the given link(s).
Args:
@@ -1150,7 +1150,7 @@ class Robot(ControllableBody):
return np.array([self.sim.get_dynamics_info(self.id, link)[0] for link in link_ids])
def get_link_frames(self, link_ids=None, flatten=False):
"""
r"""
Return the link frame position and orientation (expressed in the world space).
Args:
@@ -1171,7 +1171,7 @@ class Robot(ControllableBody):
flatten)
def get_link_frame_world_positions(self, link_ids=None, flatten=False):
"""
r"""
Return the frame position (in the Cartesian world space coordinates) of the given link(s).
Args:
@@ -1195,7 +1195,7 @@ class Robot(ControllableBody):
return pos # 2D array
def get_link_frame_world_orientations(self, link_ids=None, flatten=False):
"""
r"""
Return the frame orientation (in the Cartesian world space) of the given link(s).
Args:
@@ -1219,7 +1219,7 @@ class Robot(ControllableBody):
return orientation # 2D array
def get_link_world_positions(self, link_ids=None, flatten=True):
"""
r"""
Return the CoM position (in the Cartesian world space coordinates) of the given link(s).
Args:
@@ -1245,7 +1245,7 @@ class Robot(ControllableBody):
return pos # 2D array
def get_link_positions(self, link_ids=None, wrt_link_id=None, flatten=True):
"""
r"""
Return the link CoM position wrt the position of another link. By default, it is the base.
Args:
@@ -1269,12 +1269,12 @@ class Robot(ControllableBody):
return p
def get_link_world_orientations(self, link_ids=None, flatten=True):
"""
r"""
Return the CoM orientation (in the Cartesian world space) of the given link(s).
Args:
link_ids (int, int[N], None): link id, or list of desired link ids. If None, get the orientation of all links
associated to actuated joints.
link_ids (int, int[N], None): link id, or list of desired link ids. If None, get the orientation of all
links associated to actuated joints.
flatten (bool): if True, it will return a 1D array of float numbers instead of an array of quaternion
Returns:
@@ -1293,12 +1293,12 @@ class Robot(ControllableBody):
return orientation # 2D array
def get_link_orientations(self, link_ids=None, wrt_link_id=None, flatten=True):
"""
r"""
Return the link CoM orientation wrt the orientation of another link. By default, it is the base.
Args:
link_ids (int, int[N], None): link id, or list of desired link ids. If None, get the orientation of all links
associated to actuated joints.
link_ids (int, int[N], None): link id, or list of desired link ids. If None, get the orientation of all
links associated to actuated joints.
wrt_link_id (int, int[N], None): the other link id(s). If None, returns the orientation wrt to the base.
flatten (bool): if True, it will return a 1D array instead of a 2D array
@@ -1323,7 +1323,7 @@ class Robot(ControllableBody):
return q
def get_link_world_linear_velocities(self, link_ids=None, flatten=True):
"""
r"""
Return the linear velocity of the link(s) expressed in the Cartesian world space coordinates.
Args:
@@ -1347,7 +1347,7 @@ class Robot(ControllableBody):
return vel # 2D array
def get_link_world_angular_velocities(self, link_ids=None, flatten=True):
"""
r"""
Return the angular velocity of the link(s) in the Cartesian world space coordinates.
Args:
@@ -1371,7 +1371,7 @@ class Robot(ControllableBody):
return vel # 2D array
def get_link_world_velocities(self, link_ids=None, flatten=True):
"""
r"""
Return the linear and angular velocities (expressed in the Cartesian world space coordinates) for the given
link(s).
@@ -1401,7 +1401,7 @@ class Robot(ControllableBody):
return vel # 2D array
def get_link_linear_velocities(self, link_ids=None, wrt_link_id=None, flatten=True):
"""
r"""
Return the linear velocity of the given link(s) wrt the other specified link(s).
Args:
@@ -1425,13 +1425,14 @@ class Robot(ControllableBody):
return v
def get_link_angular_velocities(self, link_ids=None, wrt_link_id=None, flatten=True):
"""
r"""
Return the angular velocity of the given link(s) wrt to the other specified link(s).
Args:
link_ids (int, int[N], None): link id, or list of desired link ids. If None, get the angular velocity of
all links associated to actuated joints.
wrt_link_id (int, int[N], None): the other link id(s). If None, returns the angular velocity wrt to the base.
wrt_link_id (int, int[N], None): the other link id(s). If None, returns the angular velocity wrt to the
base.
flatten (bool): if True, it will return a 1D array instead of a 2D array
Returns:
@@ -1449,13 +1450,14 @@ class Robot(ControllableBody):
return w
def get_link_velocities(self, link_ids=None, wrt_link_id=None, flatten=True):
"""
r"""
Return the linear and angular velocity of the given link(s) wrt to the other specified link(s).
Args:
link_ids (int, int[N], None): link id, or list of desired link ids. If None, get the angular velocity of
all links associated to actuated joints.
wrt_link_id (int, int[N], None): the other link id(s). If None, returns the angular velocity wrt to the base.
wrt_link_id (int, int[N], None): the other link id(s). If None, returns the angular velocity wrt to the
base.
flatten (bool): if True, it will return a 1D array instead of a 2D array
Returns:
@@ -1602,8 +1604,9 @@ class Robot(ControllableBody):
# Transforms #
##############
def get_homogeneous_transform(self, position, orientation):
"""
@staticmethod
def get_homogeneous_transform(position, orientation):
r"""
Return the Homogeneous transform matrix given the position vector and the orientation.
Args:
@@ -1635,7 +1638,7 @@ class Robot(ControllableBody):
# TODO: allow to slice the Jacobian to only get what interests the user
def get_jacobian(self, link_id, q=None, local_position=None):
"""
r"""
Return the full geometric Jacobian matrix :math:`J(q) = [J_{lin}(q), J_{ang}(q)]^T`, such that:
.. math:: v = [\dot{p}, \omega]^T = J(q) \dot{q}
@@ -1675,7 +1678,7 @@ class Robot(ControllableBody):
return self.sim.calculate_jacobian(self.id, link_id, local_position=local_position, q=q, dq=dq, des_ddq=dq)
def get_linear_jacobian(self, link_id, q=None, local_position=None):
"""
r"""
Return the full linear (geometric) Jacobian matrix :math:`J_{lin}(q)`, such that:
.. math:: \dot{p} = J_{lin}(q) \dot{q}
@@ -1699,7 +1702,7 @@ class Robot(ControllableBody):
return self.get_jacobian(link_id, q, local_position)[:3]
def get_angular_jacobian(self, link_id, q=None, local_position=None):
"""
r"""
Return the full angular (geometric) Jacobian matrix :math:`J_{ang}(q)`, such that:
.. math:: \omega = J_{ang}(q) \dot{q}
@@ -1722,17 +1725,18 @@ class Robot(ControllableBody):
"""
return self.get_jacobian(link_id, q, local_position)[3:]
def get_jacobian_derivative_rpy_to_angular_velocity(self, rpy_angle):
"""
@staticmethod
def get_jacobian_derivative_rpy_to_angular_velocity(rpy_angle):
r"""
Return the Jacobian that maps RPY angle rates to angular velocities, i.e. :math:`\omega = T(\phi) \dot{\phi}`.
Warnings: :math:`T` is singular when the pitch angle :math:`\theta_p = \pm \frac{\pi}{2}`
Args:
rpy_angle (float[3]): RPY Euler angles [rad]
rpy_angle (np.float[3]): RPY Euler angles [rad]
Returns:
float[3,3]: Jacobian matrix that maps RPY angle rates to angular velocities.
np.float[3,3]: Jacobian matrix that maps RPY angle rates to angular velocities.
"""
r, p, y = rpy_angle
T = np.array([[1., 0., np.sin(p)],
@@ -1740,17 +1744,18 @@ class Robot(ControllableBody):
[0., np.sin(r), np.cos(p) * np.cos(r)]])
return T
def get_jacobian_derivative_zyz_to_angular_velocity(self, zyzAngle):
"""
@staticmethod
def get_jacobian_derivative_zyz_to_angular_velocity(zyzAngle):
r"""
Return the Jacobian that maps ZYZ angle rates to angular velocities, i.e. :math:`\omega = T(\phi) \dot{\phi}`.
Warnings: :math:`T` is singular when the angle associated with `Y` is :math:`0` or :math:`\pi`.
Args:
rpyAngle (float[3]): ZYZ Euler angles [rad]
rpyAngle (np.float[3]): ZYZ Euler angles [rad]
Returns:
float[3,3]: Jacobian matrix that maps ZYZ angle rates to angular velocities.
np.float[3,3]: Jacobian matrix that maps ZYZ angle rates to angular velocities.
"""
z, y = zyzAngle[:2]
T = np.array([[0., -np.sin(z), np.cos(z) * np.sin(y)],
@@ -1759,7 +1764,7 @@ class Robot(ControllableBody):
return T
def get_analytical_jacobian(self, jacobian, rpy_angle):
"""
r"""
Return the analytical Jacobian :math:`J_{a}(q) = [J_{lin}(q), J_{\phi}(q)]^T`, which respects:
.. math:: \dot{x} = [\dot{p}, \dot{\phi}]^T = J_{a}(q) \dot{q}
@@ -1785,12 +1790,12 @@ class Robot(ControllableBody):
Euler angles then T is singular when the pitch angle :math:`\theta_p = \pm \frac{\pi}{2}.
Args:
jacobian (float[6,N], float[6,6+N]): full geometric Jacobian.
rpy_angle (float[3]): RPY Euler angles
jacobian (np.float[6,N], np.float[6,6+N]): full geometric Jacobian.
rpy_angle (np.float[3]): RPY Euler angles
Returns:
float[6,N], foat[6,(6+N)]: the full analytical Jacobian. The number of columns depends if the base is fixed
or floating.
np.float[6,N], np.foat[6,(6+N)]: the full analytical Jacobian. The number of columns depends if the base
is fixed or floating.
"""
T = self.get_jacobian_derivative_rpy_to_angular_velocity(rpy_angle)
Tinv = np.linalg.inv(T)
@@ -1799,7 +1804,7 @@ class Robot(ControllableBody):
return Ja
def get_angular_velocities_from_derivative_rpy(self, rpy_angle, dRPY):
"""
r"""
Return the angular velocities :math:`\omega` from the derivative of RPY Euler angles \math:`\dot{\phi}`.
These 2 quantities are related by the following equation:
@@ -1818,17 +1823,17 @@ class Robot(ControllableBody):
Note that :math:`T` is singular when the pitch angle :math:`\theta_p = \pm \frac{\pi}{2}`.
Args:
rpy_angle (float[3]): RPY Euler angles [rad]
dRPY (float[3]): time derivative of RPY Euler angles [rad/s]
rpy_angle (np.float[3]): RPY Euler angles [rad]
dRPY (np.float[3]): time derivative of RPY Euler angles [rad/s]
Returns:
float[3]: angular velocities [rad/s]
np.float[3]: angular velocities [rad/s]
"""
T = self.get_jacobian_derivative_rpy_to_angular_velocity(rpy_angle)
return T.dot(dRPY)
def get_derivative_rpy_from_angular_velocities(self, rpy_angle, angular_velocity):
"""
r"""
Return the time derivative of RPY Euler angles :math:`\dot{\phi}` given the angular velocities :math:`\omega`.
. .math:: \dot{\phi} = T^{-1}(\phi) \omega
@@ -1837,11 +1842,11 @@ class Robot(ControllableBody):
corresponding angular velocities :math:`\omega` are not defined.
Args:
rpy_angle (float[3]): RPY Euler angles [rad]
angular_velocity (float[3]): angular velocities [rad/s]
rpy_angle (np.float[3]): RPY Euler angles [rad]
angular_velocity (np.float[3]): angular velocities [rad/s]
Returns:
float[3]: time derivative of RPY Euler angles [rad/s]
np.float[3]: time derivative of RPY Euler angles [rad/s]
Raises:
LinAlgError: if singular configuration.
@@ -1850,20 +1855,22 @@ class Robot(ControllableBody):
Tinv = np.linalg.inv(T)
return Tinv.dot(angular_velocity)
def get_JJT(self, jacobian):
"""
@staticmethod
def get_JJT(jacobian):
r"""
Given the Jacobian, it returns :math:`JJ^T`. This relation is used in many places in robotics.
Args:
jacobian (float[D,N]): Jacobian matrix
jacobian (np.float[D,N]): Jacobian matrix
Returns:
float[D,D]: :math:`JJ^T`
np.float[D,D]: :math:`JJ^T`
"""
return jacobian.dot(jacobian.T)
def get_damped_least_squares_inverse(self, jacobian, damping_factor=0.01):
"""
@staticmethod
def get_damped_least_squares_inverse(jacobian, damping_factor=0.01):
r"""
Return the damped least-squares (DLS) inverse, given by:
.. math:: \hat{J} = J^T (JJ^T + k^2 I)^{-1}
@@ -1872,11 +1879,11 @@ class Robot(ControllableBody):
:math:`\dot{q} = \hat{J} v`.
Args:
jacobian (float[D,N]): Jacobian matrix
jacobian (np.float[D,N]): Jacobian matrix
damping_factor (float): damping factor
Returns:
float[N,D]: DLS inverse matrix
np.float[N,D]: DLS inverse matrix
"""
J, k = jacobian, damping_factor
return (J.T).dot(np.linalg.inv(J.dot(J.T) + k**2 * np.identity(J.shape[0])))
@@ -1884,30 +1891,31 @@ class Robot(ControllableBody):
# alias
getDLSInverse = get_damped_least_squares_inverse
def get_pinv_jacobian(self, jacobian):
"""
@staticmethod
def get_pinv_jacobian(jacobian):
r"""
Return the right pseudo-inverse of the jacobian, i.e. :math:`J^\dagger = J^T(JJ^T)^{-1}`.
Args:
jacobian (float[D,N]): Jacobian matrix
jacobian (np.float[D,N]): Jacobian matrix
Returns:
float[N,N]: right pseudo-inverse of the Jacobian
np.float[N,N]: right pseudo-inverse of the Jacobian
"""
return np.linalg.pinv(jacobian)
def get_null_space_projector(self, jacobian):
"""
r"""
The null space projector :math:`P` is the matrix that projects any vectors to the null space of :math:`J`.
This is given by: :math:`P = (I - J^\dagger J)`, where :math:`J^\dagger = J^T(JJ^T)^{-1}` is the right
pseudo-inverse of the jacobian :math:`J`. This is notably used to perform inverse kinematics, where
:math:`\dot{q} = J^\dagger v + P \dot{q}_0` with :math:`\dot{q}_0` representing arbitrary joint velocities.
Args:
jacobian (float[D,N]): Jacobian matrix
jacobian (np.float[D,N]): Jacobian matrix
Returns:
float[N,N]: null space projector matrix
np.float[N,N]: null space projector matrix
"""
J = jacobian
JJT = self.get_JJT(jacobian)
@@ -1915,13 +1923,13 @@ class Robot(ControllableBody):
return I - self.get_pinv_jacobian(J=J).dot(J)
def compute_manipulability_measure(self, jacobian):
"""
r"""
Compute the manipulability measure `w(q) = sqrt( det(J(q)J(q)^T) )`. This is useful to get a general sense
about the manipulation ability of the manipulator. This term, for instance, vanishes at singular
configurations (see [1]).
Args:
jacobian (float[D,N]): Jacobian matrix
jacobian (np.float[D,N]): Jacobian matrix
Returns:
float: manipulability measure :math:`w(q)`
@@ -1931,8 +1939,9 @@ class Robot(ControllableBody):
"""
return np.sqrt(np.linalg.det(self.get_JJT(jacobian)))
def in_singular_configuration(self, jacobian):
"""
@staticmethod
def in_singular_configuration(jacobian):
r"""
Return True if we are in a singular configuration.
Singularities are interesting because (see [1]):
@@ -1941,7 +1950,7 @@ class Robot(ControllableBody):
- around them, small velocities in the task/operational space may cause large velocities in the joint space
Args:
jacobian (float[D,N]): Jacobian matrix
jacobian (np.float[D,N]): Jacobian matrix
Returns:
bool: True if in a singular configuration
@@ -1956,7 +1965,7 @@ class Robot(ControllableBody):
return r < m
def get_joint_velocities_from_cartesian_velocities(self, jacobian, velocity):
"""
r"""
Return the joint velocities :math:`\dot{q}` from the cartesian velocities :math:`v`.
.. math:: \dot{q} = J^\dagger v
@@ -1964,24 +1973,25 @@ class Robot(ControllableBody):
where :math:`J^\dagger` is the right pseudo-inverse of J, i.e. :math:`J^\dagger = J^T(JJ^T)^{-1}`.
Args:
jacobain (float[3,N], float[6,N]): Jacobian matrix
velocity (float[3], float[6]): linear and/or angular velocities
jacobain (np.float[3,N], np.float[6,N]): Jacobian matrix
velocity (np.float[3], np.float[6]): linear and/or angular velocities
Returns:
float[N]: joint velocities
np.float[N]: joint velocities
"""
Jpinv = self.get_pinv_jacobian(jacobian)
return Jpinv.dot(velocity)
def get_cartesian_velocities_from_joint_velocities(self, jacobian, dq):
"""
@staticmethod
def get_cartesian_velocities_from_joint_velocities(jacobian, dq):
r"""
Return the Cartesian velocities :math:`v = [\dot{p}, \omega]^T` where :math:`\dot{p}` and :math:`\omega`
are the linear and angular velocities, respectively.
.. math:: v = J(q) \dot{q}
Returns:
float[6]: Cartesian linear and angular velocities
np.float[6]: Cartesian linear and angular velocities
"""
return jacobian.dot(dq)
@@ -1989,7 +1999,7 @@ class Robot(ControllableBody):
def calculate_inverse_kinematics(self, link_id, position, orientation=None, lower_limits=None, upper_limits=None,
joint_ranges=None, rest_poses=None, joint_dampings=None, max_iters=1,
threshold=1e-4):
"""
r"""
Compute the FULL Inverse kinematics; it will return a position for all the actuated joints.
Args:
@@ -2025,7 +2035,7 @@ class Robot(ControllableBody):
threshold=threshold)
def hard_priorities(self, jacobians, task_velocities, method='backtrack'):
"""
r"""
Return dq.
Args:
+2
View File
@@ -71,6 +71,8 @@ class Bullet(Simulator):
sim = Bullet()
References:
[1] "PyBullet, a Python module for physics simulation for games, robotics and machine learning", Erwin Coumans
and Yunfei Bai, 2016-2019
[1] PyBullet Quickstart Guide: https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA
Erwin Coumans and Yunfei Bai, 2017/2018
"""