Authored by: Sharwin Patil (LinkedIn) (Website)
- Table Of Contents
- Getting Started
- Building, Testing, and Launching
- Running with Docker
- Usage & Examples
- Potential Field Equations
- Contributing
The potential_fields repository provides an implementation of artifical potential field methods for path planning and shared control of robotic manipulators. The package is designed to be modular and extensible, allowing users to easily integrate it with different robot platforms and kinematics solvers. This package was developed with ROS 2 Jazzy in mind, but the core C++ library is ROS-agnostic and can be used independently. I plan to extend support to future ROS distributions as they are released.
This package is split into two parts:
- Core C++ libraries (ROS-agnostic)
- ROS integration (3 ROS packages for core node, msg/srv definitions, and demos)
Repository Folder Structure
# Core C++ potential field library (ROS-agnostic)
potential_fields_library
├── cmake
├── include
│ ├── pfield
│ └── solvers
└── src
├── pfield
└── solvers
# ROS 2 package integrating the core library with ROS interfaces
potential_fields
├── config # Config files (ROS Parameters, RViz config)
├── include
│ └── potential_fields
│ ├── robot_plugins # Headers for custom robot plugins and IK Solvers
│ └── ros # ROS node headers
├── launch
├── src
│ ├── robot_plugins
│ └── ros
└── test
└── resources
# ROS 2 message and service definitions
potential_fields_interfaces
├── include
│ └── potential_fields_interfaces
├── msg
├── src
└── srv
# Example ROS 2 Package demonstrating potential_fields usage
potential_fields_demos
├── config
├── include
│ └── potential_fields_demos
├── launch
├── meshes
├── potential_fields_demos
├── src
└── urdfClone the repository with either HTTPS or SSH (depending on what you have setup for git):
# HTTPS Clone
git clone https://github.com/argallab/potential_fields.git
# SSH Clone
git clone git@github.com:argallab/potential_fields.gitOnce this repository is cloned, you will need to install the required dependencies locally on your machine before being able to build and launch the potential_fields package.
sudo apt-get update
sudo apt-get install -y libeigen3-dev liburdfdom-dev libfcl-dev libccd-dev libassimp-dev lsb-release
sudo apt-get install -y ros-${ROS_DISTRO}-urdfBelow, I've outlined the steps to install Pinocchio via robotpkg. The original documentation can be found on the pinocchio repository.
This package uses Pinocchio for rigid body dynamics. It is recommended to install it via robotpkg.
# Add robotpkg to apt sources
sudo mkdir -p /etc/apt/keyrings
curl -fsSL http://robotpkg.openrobots.org/packages/debian/robotpkg.asc | sudo tee /etc/apt/keyrings/robotpkg.asc
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/robotpkg.asc] http://robotpkg.openrobots.org/packages/debian/pub $(lsb_release -cs) robotpkg" | sudo tee /etc/apt/sources.list.d/robotpkg.list
# Install pinocchio
sudo apt-get update
sudo apt-get install -y robotpkg-pinocchioYou need to add the robotpkg installation paths to your environment. Add the following lines to the end of your ~/.bashrc (or ~/.zshrc):
export PATH=/opt/openrobots/bin:$PATH
export PKG_CONFIG_PATH=/opt/openrobots/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/opt/openrobots/lib:$LD_LIBRARY_PATH
export PYTHONPATH=/opt/openrobots/lib/python3.10/site-packages:$PYTHONPATH
export CMAKE_PREFIX_PATH=/opt/openrobots/lib/cmake:$CMAKE_PREFIX_PATHIf you're working in VS Code like I do, it will be helpful to add external dependency include paths to the editor's include path to get access to all of the useful intellisense features. Below are my settings (.vscode/c_cpp_properties.json) for the workspace to allow VS Code to recognize ROS, Eigen, and Pinocchio types, syntax highlight, and support Ctrl+Click for definitions.
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/opt/ros/jazzy/include/**",
"/usr/include/eigen3/**",
"/opt/openrobots/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "linux-clang-x64",
"configurationProvider": "ms-vscode.cpptools"
}
],
"version": 4
}To build the workspace, use colcon to build the project and run the unit tests:
colcon buildsource install/setup.bashcolcon test && colcon test-result --verboseUse pf_demo.launch.xml to launch the demo node that also launches the potential_fields package (pfield.launch.xml):
ros2 launch potential_fields_demos pf_demo.launch.xmlLaunching the project without any arguments is good enough to launch a basic potential field and visualization. Of course, arguments are necessary to customize the PF package with your robot, RViz config, gain parameters, etc.
This repository provides two Dockerfiles in the Docker/ directory:
Dockerfile(Default): Contains the full environment including the XArm SDK, MoveIt, and other dependencies required to run the full XArm7 demo.Dockerfile.minimal: A lightweight image containing only the essential dependencies (ROS 2 Jazzy, Pinocchio, Eigen, etc.) required to build and test the core library and basic demos.
To build the Full Demo Image (Recommended for trying out the XArm demo):
# Get the absolute path to the project root
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Build using the default Dockerfile
docker build -t potential_fields -f "$PROJECT_ROOT/Docker/Dockerfile" "$PROJECT_ROOT"To build the Minimal Image (Faster build, good for CI or core development):
# Build using Dockerfile.minimal
docker build -t potential_fields_minimal -f "$PROJECT_ROOT/Docker/Dockerfile.minimal" "$PROJECT_ROOT"Before running the container, ensure that your X server allows connections from Docker containers so RViz can display properly.
# Allow local connections to X server (be careful with security on public networks)
xhost +local:docker > /dev/null 2>&1Run the container (replace potential_fields with potential_fields_minimal if you built the minimal image so you can have both images on your system):
docker run -it --rm \
--net=host \
--privileged \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--volume="$PROJECT_ROOT:/home/workspace/src/potential_fields" \
potential_fieldsAfter building the image, you don't need to rebuild it unless you make changes to the code or dependencies. You can run the container multiple times using the same image:
# Start the container from the existing image
docker start -it potential_fieldsNow that you are setup with the package, know how to build and launch the package, and have a working Docker setup (if you choose to use Docker), you can explore the demos in the potential_fields_demos package.
The primary entry point for the demos is pf_demo.launch.xml. This launch file starts the potential field manager, the visualization (RViz), and a demo node that interacts with the potential field.
To launch the XArm7 demo (The robot tested in the videos on my website):
ros2 launch potential_fields_demos pf_demo.launch.xml urdf_file_path:=xarm7.urdf use_rviz:=false motion_plugin_type:=xarm end_effector_frame:=link_eefYou can customize the behavior by passing arguments to the launch command:
urdf_file_path: Path to the robot's URDF file (relative topotential_fields_demos/urdffor the demo launch).motion_plugin_type: Specifies which robot plugin to load (e.g.,xarm,franka, or leave empty fornull).end_effector_frame: The name of the link to control (e.g.,link_eef,panda_hand).rviz_fixed_frame: The fixed frame for visualization (default:world).use_rviz: Set tofalseto run without the GUI (if using a headless setup or with a MoveIt robot that launches RViz for you).
If you are integrating this into your own robot package, you will likely include the core launch file pfield.launch.xml from the potential_fields package directly.
<include file="$(find-pkg-share potential_fields)/launch/pfield.launch.xml">
<arg name="urdf_file_path" value="$(var my_urdf_path)"/>
<arg name="motion_plugin_type" value="my_robot_plugin"/>
<!-- ... other arguments ... -->
</include>The library uses two Abstract Base Classes (ABCs) to decouple the core potential field logic from specific robot hardware and kinematics solvers.
-
pfield::IKSolver(ik_solver.hpp)- Purpose: Pure mathematical interface for Inverse Kinematics. It converts a desired Cartesian pose (or twist) into joint configurations (or velocities).
- Key Method:
solve(...)takes a target pose and seed configuration, returning the joint solution and Jacobian. - When to implement: If your robot has a custom analytical solver or you want to wrap a specific numerical solver (like KDL, Trac-IK, or a vendor API).
-
MotionPlugin(motion_plugin.hpp)- Purpose: The hardware abstraction layer. It handles communication with the robot controller.
- Key Methods:
readRobotState(...): Fetches current joint angles and EE pose.sendCartesianTwist(...)/sendJointStates(...): Sends commands to the robot.getIKSolver(): Returns the specificIKSolverinstance associated with this robot.
- When to implement: For every new robot platform. This class usually instantiates and owns the
IKSolver.
Step 1: Create Files
- Create
MyRobotIKSolverinheriting frompfield::IKSolverinpotential_fields_library. - Create
MyRobotPlugininheriting fromMotionPlugininpotential_fields. This class should instantiateMyRobotIKSolver.
Step 2: Edit pfield_manager.cpp
To make the manager aware of your new classes, you must manually register them in the source code:
- Include Header: Add the include at the top of
potential_fields/src/ros/pfield_manager.cpp.#include "robot_plugins/my_robot_plugin.hpp"
- Instantiate: Add a condition in the constructor (around line 150) to check for your plugin name.
else if (this->motionPluginType == "my_robot") { // Retrieve any specific parameters if needed this->motionPlugin = std::make_unique<MyRobotPlugin>(); }
There is a README.md in the potential_fields_library folder that contains information about the independent C++ library with regards to:
- Building library with colcon or cmake
- Creating an instance of
PotentialFieldand using its functions - How to pass URDF paths, mesh resource paths, and custom inverse kinematics functions into the library for use when planning.
For information about the mathematical formulation of potential fields used in this package, see MATH.md. This README provides an overview of the package structure, instructions for building and launching the package, and details about usage.
See CONTRIBUTING.md for details on how to contribute to this repository. There's a bunch of open issues that detail possible improvements, features, and bug fixes that you can help with! Of course, feel free to open new issues or reach out to me if you have any questions.
Copyright Notice Sharwin Patil 2025
Contact me at:
sharwinpatil@u.northwestern.edu