Class PotentialField
Defined in File pfield.hpp
Class Documentation
-
class PotentialField
Public Types
-
using ControlPoint = std::pair<Eigen::Vector3d, double>
A world-space point on a robot link surface used for repulsion queries.
pointis the world-frame location;surfaceRadiusis the local geometry radius at that point (e.g. capsule radius, sphere radius; 0 for box corners). Clearance to an obstacle is computed assdf(point) - surfaceRadius.
Public Functions
-
inline PotentialField()
-
~PotentialField() = default
-
inline PotentialField(const PotentialField &other)
-
inline explicit PotentialField(SpatialVector goalPose)
Constructs a PotentialField with the specified goal position. The attractive gain and rotational attractive gain are set to default values.
- Parameters:
goalPose – The pose in 3D space that will generate an attractive force.
-
inline PotentialField(SpatialVector goalPose, double attractiveGain, double repulsiveGain, double rotationalAttractiveGain)
-
inline PotentialField(double attractiveGain, double repulsiveGain, double rotationalAttractiveGain)
-
inline PotentialField(double attractiveGain, double repulsiveGain, double rotationalAttractiveGain, double maxLinearVelocity, double maxAngularVelocity, double influenceDistance)
-
inline PotentialField(double attractiveGain, double repulsiveGain, double rotationalAttractiveGain, double maxLinearVelocity, double maxAngularVelocity, double maxLinearAcceleration, double maxAngularAcceleration, double influenceDistance)
-
inline PotentialField(SpatialVector goalPose, double attractiveGain, double repulsiveGain, double rotationalAttractiveGain, double maxLinearVelocity, double maxAngularVelocity, double maxLinearAcceleration, double maxAngularAcceleration, double influenceDistance)
-
inline PotentialField &operator=(const PotentialField &other)
-
inline bool operator==(const PotentialField &other) const
-
inline bool operator!=(const PotentialField &other) const
-
void initializeKinematics(const std::string &urdfFilePath, const std::string &eeLinkName)
Initializes the PFKinematics module with the given URDF file path and end-effector link name.
Note
The end-effector link name must match a link in the URDF model and will be the frame used for planning.
- Parameters:
urdfFilePath – The file path to the robot’s URDF file.
eeLinkName – The name of the end-effector link in the robot model.
-
inline void setAttractiveGain(double newAttractiveGain)
-
inline void setRepulsiveGain(double newRepulsiveGain)
-
inline void setRotationalAttractiveGain(double newRotationalAttractiveGain)
-
inline void setMaxLinearVelocity(double newMaxLinearVelocity)
-
inline void setMaxAngularVelocity(double newMaxAngularVelocity)
-
inline void setMaxLinearAcceleration(double newMaxLinearAcceleration)
-
inline void setMaxAngularAcceleration(double newMaxAngularAcceleration)
-
inline void setInfluenceDistance(double newInfluenceDistance)
-
inline void setGoalPose(SpatialVector newGoalPose)
-
inline void clearGoalPose()
-
inline void setQuadraticThreshold(double threshold)
-
inline void enableDynamicQuadraticThreshold(bool enabled)
-
inline double getAttractiveGain() const
-
inline double getRepulsiveGain() const
-
inline double getRotationalAttractiveGain() const
-
inline double getMaxLinearVelocity() const
-
inline double getMaxAngularVelocity() const
-
inline double getMaxLinearAcceleration() const
-
inline double getMaxAngularAcceleration() const
-
inline double getInfluenceDistance() const
-
inline double getRotationalThreshold() const
-
inline double getQuadraticThreshold() const
-
inline size_t getNumJoints() const
-
inline size_t getNumLinks() const
-
inline bool isUsingDynamicQuadraticThreshold() const
-
inline bool isGoalSet() const
-
inline SpatialVector getGoalPose() const
-
inline std::vector<PotentialFieldObstacle> getEnvObstacles() const
-
inline std::vector<PotentialFieldObstacle> getRobotObstacles() const
-
std::pair<SpatialVector, TaskSpaceTwist> stepIntegration(const SpatialVector ¤tPose, const TaskSpaceTwist &prevTwist, const double dt, const std::string &integrationMethod, std::vector<double> &jointAngles, const std::vector<double> &jointVelocities = {})
Integrates the current pose forward in time based on the potential field.
- Parameters:
currentPose – The current pose of the robot/query point.
prevTwist – The previous twist (for acceleration limiting).
dt – The time step [s].
integrationMethod – The method to use: “task_space” or “whole_body”.
jointAngles – Current joint angles (required for “whole_body”, updated via IK for “task_space”).
jointVelocities – Previous joint velocities (required for “whole_body”).
- Returns:
A pair containing the new SpatialVector and the TaskSpaceTwist applied.
-
void updateObstaclesFromKinematics(const std::vector<double> &jointAngles)
Given a new set of joint angles, updates the internal obstacles based on the robot kinematics.
Note
This function requires that PFKinematics has been initialized using initializeKinematics prior to calling this function.
- Parameters:
jointAngles – The new joint angles to compute the updated obstacle poses [rad]
-
void addObstacle(PotentialFieldObstacle obstacle)
Adds a new obstacle to the potential field.
- Parameters:
obstacle – The obstacle to be added.
-
void addObstacles(const std::vector<PotentialFieldObstacle> &obstacles)
Adds multiple obstacles to the potential field.
- Parameters:
obstacles – The obstacles to be added.
-
bool removeObstacle(const std::string &obstacleFrameID)
Attempts to remove an obstacle by ID.
Note
If the obstacle is not found, no action is taken.
- Parameters:
obstacleFrameID – the frame ID of the obstacle obtained on obstacle creation.
- Returns:
true if the obstacle was removed successfully.
-
void clearObstacles()
Clears all obstacles from the potential field.
-
PotentialFieldObstacle getObstacleByID(const std::string &obstacleFrameID) const
Gets an obstacle by its frame ID.
- Parameters:
obstacleFrameID – the frame ID of the obstacle to retrieve.
- Returns:
PotentialFieldObstacle The obstacle with the specified frame ID.
-
std::vector<PotentialFieldObstacle> getObstaclesByGroup(ObstacleGroup group) const
Gets all of the obstacles belonging to a specific group.
Note
Obstacle groups are [STATIC, DYNAMIC, ROBOT]
- Parameters:
group – The group to filter obstacles by.
- Returns:
std::vector<PotentialFieldObstacle> A vector of obstacles belonging to the specified group.
-
bool isPointInsideObstacle(Eigen::Vector3d worldPoint) const
Determines if the given point (in the world frame) is inside any obstacle.
- Parameters:
worldPoint – The point in world coordinates to check.
- Returns:
true If the point is inside any obstacle.
-
bool isPointWithinInfluenceZone(Eigen::Vector3d worldPoint) const
Determines if the given point (in the world frame) is within the influence zone of any obstacle.
- Parameters:
worldPoint – The point in world coordinates to check.
- Returns:
true If the point is within the influence zone of any obstacle.
-
PFLimits computeFieldBounds(const SpatialVector &queryPose, double bufferArea) const
Computes the spatial limits (bounding box) of the potential field for visualization or analysis. The bounds encompass all obstacles, the goal, and the query pose, expanded by a buffer area.
- Parameters:
queryPose – The current query pose to include in the bounds
bufferArea – The extra margin to add around the computed limits [m]
- Returns:
PFLimits The computed spatial limits
-
Eigen::VectorXd evaluateWholeBodyJointTorquesAtConfiguration(const std::vector<double> &jointAngles, const std::vector<double> &prevJointVelocities, const SpatialVector &eePose, const double dt, std::vector<Eigen::Vector3d> *outLinkForces = nullptr, std::vector<double> *outLinkClearances = nullptr, Eigen::Vector3d *outAttractionForce = nullptr)
Computes the whole-body joint velocities resulting from the combination of the attractive and repulsive forces at the given configuration and joint velocities.
- Parameters:
jointAngles – [in] The current joint angles of the robot [rad]
prevJointVelocities – [in] The previous joint velocities of the robot [rad/s]
eePose – [in] The current end-effector pose
dt – [in] The time step over which to integrate acceleration [s]
outLinkForces – [out] A vector of linear forces acting on each link [N]
outLinkClearances – [out] A vector of minimum clearances between each link and obstacles [m]
outAttractionForce – [out] The linear force vector acting on the end-effector [N]
- Returns:
Eigen::VectorXd The resulting whole-body joint velocities [rad/s]
-
TaskSpaceTwist evaluateWholeBodyTaskSpaceTwistAtConfiguration(const std::vector<double> &jointAngles, const std::vector<double> &prevJointVelocities, const SpatialVector &eePose, const double dt)
Computes the task-space twist resulting from whole-body joint velocities.
- Parameters:
jointAngles – The current joint angles of the robot [rad]
prevJointVelocities – The previous joint velocities of the robot [rad/s]
dt – The time step over which to integrate acceleration [s]
eePose – The current end-effector pose
- Returns:
TaskSpaceTwist The resulting task-space twist
-
TaskSpaceWrench evaluateWrenchAtPose(const SpatialVector &queryPose) const
Given a 3D position, computes the task-space wrench by combining attractive and repulsive forces.
- Parameters:
queryPose – The pose in 3D space to compute the wrench.
- Returns:
TaskSpaceWrench The resultant task-space wrench [N, Nm]
-
TaskSpaceTwist evaluateVelocityAtPose(const SpatialVector &queryPose) const
Given a 3D position, computes the task-space twist (velocity) by combining attractive and repulsive forces and converting to velocity vectors.
- Parameters:
queryPose – The pose in 3D space to compute the velocity
- Returns:
TaskSpaceTwist The resultant task-space twist [m/s, rad/s]
-
TaskSpaceTwist evaluateLimitedVelocityAtPose(const SpatialVector &queryPose, const TaskSpaceTwist &prevTwist = TaskSpaceTwist(), const double dt = 0.0) const
Performs the same operation as evaluateVelocityAtPose but applies velocity limits to the resulting twist.
Note
This function allows you to provide the previous twist and time step for acceleration limiting, but can be called with default parameters to only apply velocity limits
-
Eigen::Vector3d removeOpposingForce(const Eigen::Vector3d &attractionForce, const Eigen::Vector3d &repulsiveForce) const
Given attraction and repulsive force vectors, mitigate local minima near broad surfaces by removing opposing components of the repulsive force.
Removes the component of the repulsive force that directly opposes the attractive force, while preserving tangential components that encourage sliding around obstacles. Formally, if u_att = F_att/||F_att|| and dot = F_rep·u_att < 0, return F_rep - dot·u_att; otherwise return F_rep. When ||F_att|| is near zero, the repulsive force is returned unchanged.
Note
This is typically applied only in planning (not in evaluateWrenchAtPose) to avoid altering the visualized field and unit-test semantics.
- Parameters:
attractionForce – Attractive linear force vector, typically calculated from computeAttractiveForceLinear.
repulsiveForce – Repulsive linear force vector, typically calculated from computeRepulsiveForceLinear.
- Returns:
Eigen::Vector3d Resultant force vector with opposing components removed
-
TaskSpaceWrench evaluateWrenchAtPoseWithOpposingForceRemoval(const SpatialVector &queryPose) const
Given a 3D position, computes the task-space wrench (force/torque) by combining attractive and repulsive forces and removing any repulsive components that oppose the attractive force to help escape local minima.
Note
This function is primarily intended for use during path planning and simply coordinates the use of computeAttractiveForceLinear, computeRepulsiveForceLinear, and removeOpposingForce to produce the final wrench.
- Parameters:
queryPose – The pose in 3D space to compute the wrench.
- Returns:
TaskSpaceWrench The resultant task-space wrench [N, Nm]
-
TaskSpaceTwist wrenchToTwist(const TaskSpaceWrench &wrench) const
Converts a task-space wrench to a task-space twist (velocity) using gain parameters converting force to velocity [m/s per N] and [rad/s per Nm].
Note
This function assumes a massless system where linearGain [(m/s)/N] and angularGain [(rad/s)/Nm] are both 1.0
- Parameters:
wrench – The task-space wrench to convert.
- Returns:
TaskSpaceTwist The resultant task-space twist [m/s, rad/s].
-
TaskSpaceTwist applyMotionConstraints(const TaskSpaceTwist &twist, const TaskSpaceTwist &prevTwist, const double dt) const
Applies velocity and acceleration limits to a task-space twist.
- Parameters:
twist – The input task-space twist to be limited
prevTwist – The previous task-space twist for acceleration limiting, can use zero if not available
dt – The time step over which to apply acceleration limits [s]
- Returns:
TaskSpaceTwist The limited task-space twist
-
SpatialVector interpolateNextPose(const SpatialVector ¤tPose, const TaskSpaceTwist &prevTwist, const double dt)
Given a current pose and a delta time, computes the next pose after the time step.
Note
This function uses both integrateLinearVelocity and integrateAngularVelocity and combines their results to compute the next pose.
- Parameters:
currentPose – The starting pose as a SpatialVector.
prevTwist – The previous task-space twist for acceleration limiting.
dt – The time step over which to compute the next pose [s].
- Returns:
SpatialVector The resulting pose after applying the velocity field for the time step.
-
Eigen::Vector3d integrateLinearVelocity(const Eigen::Vector3d ¤tPosition, const Eigen::Vector3d &linearVelocity, double deltaTime)
Given a current position, an instantaneous linear velocity vector, and a delta time, integrates the linear velocity to compute the new position after the time step.
- Parameters:
currentPosition – The starting position as a 3D vector.
linearVelocity – The instantaneous linear velocity vector in meters per second.
deltaTime – The time step over which to integrate the linear velocity [s].
- Returns:
Eigen::Vector3d The resulting position after integrating the linear velocity.
-
Eigen::Quaterniond integrateAngularVelocity(const Eigen::Quaterniond ¤tOrientation, const Eigen::Vector3d &angularVelocity, double deltaTime)
Given a current orientation and a delta time, computes the angular velocity to compute the new orientation after the time step.
- Parameters:
currentOrientation – The starting orientation as a quaternion.
angularVelocity – The instantaneous angular velocity vector in radians per second.
deltaTime – The time step over which to integrate the angular velocity [s].
- Returns:
Eigen::Quaterniond The resulting orientation after integrating the angular velocity.
-
Eigen::VectorXd convertJointTorquesToJointVelocities(const Eigen::VectorXd &jointTorques, const std::vector<double> &jointAngles, const std::vector<double> &prevJointVelocities, const double dt) const
Converts joint torques to joint velocities utilizing the robot dynamics equation or a simple proportional gain.
The full robot dynamics equation, where joint accelerations (q̈) are integrated to get joint velocities (q̇): M(q)·q̈ = τ − C(q,q̇)·q̇ − G(q) − D·q̇ If the robot dynamics equation is disabled, it uses a simple proportional gain: q̇ = torqueToVelocityGain · τ
Note
This function currently always disables the Robot Dynamics Equation due to bugs (see Issue #23).
- Parameters:
jointTorques – Generalized joint torques [Nm].
jointAngles – Current joint configuration [rad].
prevJointVelocities – Previous joint velocities for Coriolis and damping [rad/s].
dt – Integration timestep [s].
- Returns:
Eigen::VectorXd Joint velocities [rad/s].
-
Eigen::Vector3d computeAttractiveForceLinear(const SpatialVector &queryPose) const
Computes the attractive force towards the goal position.
Note
Equation: F = -attractiveGain * (distance * direction)
- Parameters:
queryPose – The pose in 3D space to compute the force from
- Returns:
Eigen::Vector3d The attractive force vector [N]
-
Eigen::Vector3d computeAttractiveMoment(const SpatialVector &queryPose) const
Computes the attractive moment (torque) to align the query pose’s orientation with the goal pose’s orientation.
Note
Equation: M = rotationalAttractiveGain * (angle * axis)
- Parameters:
queryPose – The pose in 3D space to compute the moment from
- Returns:
Eigen::Vector3d The attractive moment vector [Nm]
-
Eigen::Vector3d computeRepulsiveForceLinear(const SpatialVector &queryPose) const
Computes the repulsive linear force from all obstacles.
Note
Equation: F = repulsiveGain * (1/distance - 1/influence) * (1 / distance^2) * direction
- Parameters:
queryPose – The position in 3D space to compute the force from
- Returns:
Eigen::Vector3d The repulsive force vector [N]
-
Eigen::VectorXd computeEndEffectorAttractionJointTorques(const SpatialVector &eePose, const std::vector<double> &jointAngles) const
Computes joint torques for end-effector attraction to the goal pose.
Note
Uses the evaluateWrenchAtPose method to compute task-space forces, then maps them to joint space via the end-effector Jacobian transpose.
- Parameters:
eePose – The current end-effector pose
jointAngles – The current joint configuration [rad]
- Returns:
Eigen::VectorXd Joint torques for end-effector attraction [Nm]
-
Eigen::VectorXd computeWholeBodyRepulsionJointTorques(const std::vector<double> &jointAngles, std::vector<Eigen::Vector3d> *outLinkForces = nullptr, std::vector<double> *outLinkClearances = nullptr) const
Computes joint torques for whole-body obstacle repulsion.
Note
Iterates over all robot links and environment obstacles, computing repulsive forces at the nearest points and mapping them to joint space via link Jacobian transposes. Uses COAL distance queries and the Khatib repulsive potential formulation.
- Parameters:
jointAngles – [in] The current joint configuration [rad]
outLinkForces – [out] A pointer to a vector to store the computed forces on each link [N]
outLinkClearances – [out] A pointer to a vector to store the minimum clearances between each link and obstacles [m]
- Returns:
Eigen::VectorXd Joint torques for whole-body obstacle avoidance [Nm]
-
TaskSpaceTwist constrainedTwistAtPose(const SpatialVector &pose, const TaskSpaceTwist &prevTwist, const double dt)
Computes the constrained twist at a given pose using the previous twist and the time step for velocity and acceleration limiting.
- Parameters:
pose – The current pose to compute the constrained twist for
prevTwist – The previous twist to use for limiting
dt – The time step for the integration
- Returns:
TaskSpaceTwist The computed constrained twist
-
std::pair<SpatialVector, TaskSpaceTwist> rungeKuttaStep(const SpatialVector ¤tPose, const TaskSpaceTwist &prevTwist, const double dt)
Computes the next pose and twist using the Runge-Kutta 4-step (RK4) integration method.
- Parameters:
currentPose – The current pose to compute the next pose from
prevTwist – The previous twist to use for the integration
dt – The time step for the integration
- Returns:
std::pair<SpatialVector, TaskSpaceTwist> The computed next pose and twist
-
double computeDynamicQuadraticThreshold(const SpatialVector &queryPose) const
Compute a per-step switch distance d* that blends goal/path clearance and stopping distance.
Note
When dynamic thresholding is disabled, the fixed dStarThreshold is used.
- Parameters:
queryPose – The current pose to compute the dynamic threshold for
- Returns:
double The computed dynamic quadratic threshold distance d* [m]
-
double minObstacleClearanceAt(const Eigen::Vector3d &point) const
Computes the minimum obstacle clearance at a given point.
Note
Returns +infinity if no obstacles are present as
std::numeric_limits<double>::infinity().- Parameters:
point – The point in 3D space to compute the clearance for
- Returns:
double The minimum clearance distance to the nearest obstacle [m]
-
double minClearanceAlongSegment(const Eigen::Vector3d &from, const Eigen::Vector3d &to, int samples = 7) const
Computes the minimum obstacle clearance along a line segment.
Note
Returns +infinity if no obstacles are present as
std::numeric_limits<double>::infinity().- Parameters:
from – The starting point of the line segment
to – The ending point of the line segment
samples – The number of samples to take along the segment (default is 7)
- Returns:
double The minimum clearance distance along the segment [m]
-
bool isRobotInCollisionWithEnvironment(double clearanceThreshold = 0.0) const
Checks if the robot is within a certain clearance distance from any environment obstacles.
- Parameters:
clearanceThreshold – The clearance distance to check against [m]
- Returns:
true If the robot is in collision with an environment obstacle
- Returns:
false If the robot is not in collision with any environment obstacles
-
PlannedPath planPathFromTaskSpaceWrench(const SpatialVector &startPose, const std::vector<double> &startJointAngles, const double dt, const double goalTolerance, const size_t maxIters = 30000)
Plans a path from the start pose to the goal pose using the potential field.
Note
The path is planned by iteratively evaluating the velocity field at the current pose, applying motion constraints, and integrating (RK4) to find the next pose until the goal is reached. The IK solver is used to translate end-effector poses to joint angles at each step.
- Parameters:
startPose – The starting pose as a SpatialVector.
startJointAngles – The starting joint angles for the robot [rad].
dt – The time step for each iteration of the path planning [s].
goalTolerance – The tolerance for reaching the goal pose [m].
maxIters – The maximum number of iterations to perform for path planning, defaults to 30000.
- Returns:
PlannedPath The planned path containing poses, twists, joint angles, and timestamps.
-
PlannedPath planPathFromWholeBodyJointVelocities(const std::vector<double> &startJointAngles, const double dt, const double goalTolerance, const size_t maxIters = 30000)
Plans a path from the starting configuration to the internal goal pose using whole-body joint velocities.
Note
This method computes joint velocities by considering both end-effector attraction to the goal and whole-body obstacle repulsion. Unlike planPathFromTaskSpaceWrench, this method directly integrates joint velocities rather than task-space velocities, providing better whole-body collision avoidance. Forward kinematics is used to compute the end-effector pose at each step from the integrated joint configuration.
- Parameters:
startJointAngles – The starting joint angles for the robot [rad].
dt – The time step for each iteration of the path planning [s].
goalTolerance – The tolerance for reaching the goal pose [m].
maxIters – The maximum number of iterations to perform for path planning, defaults to 30000.
- Returns:
PlannedPath The planned path containing poses, twists, joint angles, and timestamps.
-
std::vector<double> computeInverseKinematics(const SpatialVector &targetPose, const std::vector<double> &seedJointAngles) const
Runs the IKSolver to compute joint angles for a desired end-effector pose.
- Parameters:
targetPose – The desired end-effector pose as a SpatialVector.
seedJointAngles – The initial guess for joint angles [rad].
- Returns:
std::vector<double> The computed joint angles [rad].
-
bool createPlannedPathCSV(const PlannedPath &path, const std::string &filePath) const
Creates a CSV file from a planned path with the following columns: Time [s], Position X [m], Position Y [m], Position Z [m], Orientation Qx, Orientation Qy, Orientation Qz, Orientation Qw, Linear Velocity X [m/s], Linear Velocity Y [m/s], Linear Velocity Z [m/s], Angular Velocity X [rad/s], Angular Velocity Y [rad/s], Angular Velocity Z [rad/s], Minimum Obstacle Clearance [m], Number of Joints Joint 1 [rad], Joint 2 [rad], …, Joint N [rad].
Note
The real header looks like: time_s, pos_x_m, pos_y_m, pos_z_m, q_x, q_y, q_z, q_w, vel_x_m_s, vel_y_m_s, vel_z_m_s, ang_vel_x_rad_s, ang_vel_y_rad_s, ang_vel_z_rad_s, min_obstacle_clearance_m, num_joints, joint_1_rad, joint_2_rad, …, joint_N_rad
- Parameters:
path – The planned path to convert to CSV
filePath – The file path to save the CSV
- Returns:
true If the CSV was created successfully
- Returns:
false If there was an error creating the CSV
Public Static Functions
-
static std::vector<ControlPoint> buildControlPoints(const PotentialFieldObstacle &link)
Computes the set of control points for a robot link obstacle.
Control points are world-space representative points on the link surface used for floating-control-point repulsion. The set depends on geometry type:
CAPSULE: two endcap centers + shaft midpoint; surfaceRadius = capsule radius.
BOX: 8 OBB corners; surfaceRadius = 0.
SPHERE: link center; surfaceRadius = sphere radius.
CYLINDER: two endcap centers + shaft midpoint; surfaceRadius = cylinder radius.
default: link center; surfaceRadius = halfDimensions().norm().
- Parameters:
link – The robot link obstacle.
- Returns:
Vector of (world point, surface radius) pairs.
-
using ControlPoint = std::pair<Eigen::Vector3d, double>