Chapter 3 · Section 6 of 10

Licences, platforms and the comparison grids

16 min read17 of 41 in Frameworks & Manipulation
On this page

The cross-cutting document: what you are allowed to ship, what will run on your machine, how it all fits into ROS 2, and every method in this area side by side.

It exists separately because these questions do not belong to reaching, or to planning, or to controlling. They are the same questions whichever part you are working on, and answering them three times is how the three quietly drift apart.

Every licence below was read from the project's own LICENSE file or package manifest, fetched in September 2026, and never from a badge or a blog. Every link was checked. Where code and weights differ, both are named.

If you read one section, read section 1. The default inverse kinematics solver in the main open-source motion planning framework is LGPL, not BSD, and almost nothing says so.

Contents#

  1. Licences, and the four that will catch you out
  2. The libraries, and what state each is in
  3. What runs on an Apple Silicon Mac
  4. ROS 2: distributions, packages and versions
  5. The comparison grids

1. Licences, and the four that will catch you out#

The good news first. The core of this area is permissive and clean. MoveIt 2, OMPL, the Pilz industrial motion planner, MoveIt Task Constructor, moveit_servo, TRAC-IK, pick_ik and bio_ik are all BSD-3. ros2_control, ros2_controllers, the admittance controller and the motion primitives controller are all Apache-2.0. Pinocchio is BSD-2, Drake is BSD-3, and — the one that surprises people — cuRobo is Apache-2.0, despite being NVIDIA research code, which is usually not.

Four things are not clean, and each catches people in a different way.

1.1 MoveIt's default IK solver is LGPL-2.1#

KDL, the Kinematics and Dynamics Library, is LGPL-2.1. GitHub's licence detector does not identify it, because the licence text lives in orocos_kdl/COPYING rather than at the repository root, so the repository shows no licence at all in the usual places. The file itself is the GNU Lesser General Public License, version 2.1.

KDL is MoveIt's default kinematics plugin, so a very large number of ROS arm projects have LGPL code in the path between "here is a pose" and "here are the joint angles" without anyone having decided that. The LGPL is much weaker than the GPL and dynamic linking is the case it was written to permit, so for most people this is a thing to know rather than a thing to fix. It is worth knowing because the assumption in the room is invariably "MoveIt is BSD, so this is BSD", and that assumption is wrong about one specific component.

If it matters, the replacements are permissive and better: TRAC-IK and pick_ik are both BSD-3.

1.2 ViSP, the visual servoing library, is GPL-2.0 or later#

ViSP is the reference implementation of visual servoing, it is actively maintained, and its LICENSE.txt is the GNU General Public License version 2 or later. The ROS wrapper vision_visp is the same code.

Visual servoing is a small enough corner that there is no permissive equivalent of comparable depth, so the practical positions are to use it and accept the obligation, to write the specific controller you need yourself — image-based servoing on a known feature is not a large piece of code — or to buy it.

1.3 Ruckig is MIT and calls a cloud API#

Ruckig is MIT, and this is not a licence problem. It is a deployment problem hiding behind a licence that looks settled.

Ruckig's own README states that the Community Version supports intermediate waypoints using a cloud API for remote calculation, that it switches to that cloud API as soon as intermediate positions are given, and that this path is not real-time capable. Local calculation of intermediate waypoints is a Pro feature, as are position limits and interrupting a calculation.

A trajectory generator that makes a network call is worth knowing about before it is in a control loop. MoveIt is not in that case — its Ruckig use smooths an existing waypoint sequence rather than supplying intermediate positions — and anyone calling Ruckig directly with intermediate_positions is.

1.4 Isaac ROS cuMotion is proprietary, and cuRobo is not#

This is the same trap the perception area found in Isaac ROS, in a different package, and it is worth restating because the two halves point opposite ways.

cuRobo itself is Apache-2.0, read from its LICENSE file. The ROS 2 packaging of it, isaac_ros_cumotion, declares NVIDIA Isaac ROS Software License in its own package.xml. That is NVIDIA's proprietary licence, not an open one, and GitHub's detector reports the repository as having no recognised licence.

So the library is permissive and the convenient way to use it from ROS is not. Both also require CUDA, so neither runs here at all.

1.5 The patterns worth recognising#

  • Code permissive, weights not. GR00T N1.5's repository is Apache-2.0 and its weights are under the NVIDIA One Way Noncommercial License, with the model card stating the model is ready for non-commercial use.
  • No licence is worse than a restrictive one. openpi's repository is Apache-2.0 and its checkpoints ship from a Google Cloud Storage bucket with no stated terms. Absent a statement, nothing is granted.
  • A licence file at the root need not describe the whole repository. Tesseract ships a LICENSE that says the package contains Apache-2.0, BSD-2 and BSD-3 code, each file marked at the top. It has to be read per file.
  • GitHub's detector is not the licence. It misses KDL entirely and reports Isaac ROS cuMotion as unlicensed. Fetch the file.

2. The libraries, and what state each is in#

Read these as: what it is, what its licence is, and what state it is in, verified by its last push in September 2026. A stale library is a slow problem rather than an obvious one.

2.1 Planning#

These are the libraries that decide a route. MoveIt is the framework and the others are either plugins inside it or alternatives to it.

LibraryLicenceState
MoveIt 2BSD-3very active, pushed daily. 2.0k stars
OMPLBSD-3active. The sampling planners underneath MoveIt
Pilz industrial motion plannerBSD-3inside MoveIt. PTP, LIN and CIRC, plus a sequence action
CHOMP and STOMPBSD-3inside MoveIt. The optimisation-based plugins
MoveIt Task ConstructorBSD-3maintained, pushed September 2026. 287 stars, which is a fair measure of how widely the idea has been taken up
Tesseract and tesseract_planningmixed Apache-2.0, BSD-2, BSD-3, marked per fileactive. The maintained TrajOpt lives here
cuRoboApache-2.0active. CUDA only
MPlibMITa lightweight planner outside ROS; last pushed May 2026

2.2 Kinematics and trajectories#

These turn poses into joint angles, and paths into timed trajectories. The first row is the licence trap from section 1.1.

LibraryLicenceState
KDLLGPL-2.1, in orocos_kdl/COPYINGactive. MoveIt's default IK
TRAC-IKBSD-3stable; last pushed June 2026. Exists because KDL fails on poses that have solutions
pick_ikBSD-3active. The modern MoveIt IK plugin
bio_ikBSD-3quiet; last pushed February 2025
PinocchioBSD-2very active, 3.7k stars. Kinematics and dynamics from a URDF
RuckigMIT, with the cloud caveat in section 1.3very active
TOPP-RAMITmaintained; last pushed August 2026
DrakeBSD-3very active, 4.2k stars. Modelling, optimisation and control

2.3 Control#

These execute the motion and decide what happens on contact. The ViSP row is the licence trap from section 1.2.

LibraryLicenceState
ros2_controlApache-2.0very active
ros2_controllersApache-2.0very active. Contains joint_trajectory_controller, admittance_controller and the new motion_primitives_controllers
moveit_servoBSD-3inside MoveIt. Real-time Cartesian jogging
FZI cartesian_controllersBSD-3stale: last pushed October 2024
ViSPGPL-2.0 or latervery active
acadosBSD-2very active. Embedded MPC
OCS2BSD-3active
CrocoddylBSD-3active
MuJoCo MPCApache-2.0active. The best way to develop an intuition for MPC

2.4 Reachability#

There are only two tools worth naming and both are quiet, which is itself the finding: reachability analysis has no healthy open-source ecosystem.

ToolLicenceState
reachApache-2.0last pushed March 2025. The maintained option
Reuleauxnone at all — no licence file in the repositoryin ROS-Industrial's attic, last pushed July 2024. Papers still cite it; do not build on it

2.5 Learned motion#

Every one of these is covered with its weights licence in section 2 of learned motion. The short version: LeRobot is Apache-2.0 and is where the ecosystem now lives; ACT, Diffusion Policy, Octo, OpenVLA, RDT-1B and Motion Policy Networks are MIT; openpi's code is Apache-2.0 and its weights are unstated; GR00T N1.5's code is Apache-2.0 and its weights are non-commercial.

3. What runs on an Apple Silicon Mac#

The headline is better than its reputation, and it is not documented anywhere obvious, so this section is the result of checking rather than of reading.

ROS 2 has no official Apple Silicon support at all. In REP-2000 — whose last distribution section is Kilted Kaiju, so Lyrical's own dates are not in it — defines the target platforms for every distribution, macOS appears only in the amd64 row at tier 3, for both Jazzy and Kilted. The arm64 row has no macOS cell. This is the same finding the perception area reports, and the practical route is the same: RoboStack, a community conda redistribution, which is what this repository uses.

And through RoboStack, nearly the whole motion stack is there. Checked against the robostack-jazzy channel: ros-jazzy-moveit 2.12.4, ros-jazzy-moveit-py, ros-jazzy-moveit-servo, ros-jazzy-ompl, ros-jazzy-pilz-industrial-motion-planner, ros-jazzy-moveit-task-constructor-core, ros-jazzy-ros2-control 4.47.0, ros-jazzy-ros2-controllers 4.42.1, ros-jazzy-ur-robot-driver, ros-jazzy-octomap, ros-jazzy-behaviortree-cpp and ros-jazzy-py-trees all publish an osx-arm64 build. So planning, Cartesian servoing, industrial motion primitives, task construction and control all run on the Mac, which is more than most people assume.

The table below is what works against what does not. Read the right column as the list of things to plan around rather than to fight.

Works on Apple SiliconDoes not
MoveIt 2, OMPL, Pilz, MoveIt Task Constructor, moveit_servo, via RoboStackcuRobo, entirely — it is built on CUDA and has no CPU path
ros2_control and ros2_controllers, via RoboStackIsaac ROS cuMotion, which needs CUDA and is proprietary besides
Pinocchio, from conda-forge and from a macosx_11_0_arm64 PyPI wheelIsaac Lab, which needs Isaac Sim and an NVIDIA card
MuJoCo and MuJoCo MPC, nativelyopenpi, whose README states an NVIDIA GPU requirement and that only Ubuntu 22.04 is supported
Drake, from a macosx_15_0_arm64 wheel — note it requires macOS 15TOPP-RA, which publishes no macOS wheel at all; build from source
Ruckig, from a macosx_11_0_arm64 wheelros-jazzy-visp and ros-jazzy-vision-visp, which RoboStack does not build
ViSP itself, from conda-forge with an osx-arm64 buildacados, which is not on conda-forge and needs building
LeRobot, which selects mps automatically when Metal is availablelarge-scale policy fine-tuning, which needs 22 GB or more of GPU memory
Stable-Baselines3 and robosuite, since MuJoCo is nativethe accelerated paths in MuJoCo Playground and Genesis

Two of those deserve a sentence rather than a cell.

LeRobot's Apple Silicon support is in the code, not merely in the README. Its device selection tries CUDA, then torch.backends.mps, and returns torch.device("mps") when Metal is available. Training a small policy and running inference both work on a Mac.

The ViSP split is the awkward one. The library has an osx-arm64 build on conda-forge, and the ROS wrapper has no RoboStack build. So visual servoing on a Mac means calling ViSP directly rather than through ROS, and the GPL obligation from section 1.2 comes with it.

4. ROS 2: distributions, packages and versions#

ROS 2's current release is Lyrical, from May 2026; ros2_controllers carries a ros2_controllers.lyrical.repos alongside its Jazzy and Kilted files. Jazzy Jalisco runs from May 2024 to May 2029 and is the safer choice today, which is what this repository uses. Kilted Kaiju ends in November 2026, so starting on it now is starting on something with two months left. Those dates are from REP-2000, and the distribution list is in rosdistro.

The packages that matter for motion, with the licence of each:

PackageLicenceWhat it is for
moveitBSD-3planning, IK, collision checking, the planning scene
moveit_servoBSD-3real-time Cartesian and joint jogging
moveit_task_constructorBSD-3planning a task as stages rather than as steps
pilz_industrial_motion_plannerBSD-3PTP, LIN, CIRC and blended sequences
ros2_controlApache-2.0the control loop and the hardware interface
joint_trajectory_controllerApache-2.0executing a planner's trajectory — read section 3 of controlling the move before trusting its defaults
admittance_controllerApache-2.0the one contact controller the open stack ships
motion_primitives_controllersApache-2.0sending PTP, LIN and CIRC to the vendor's own controller
force_torque_sensor_broadcasterApache-2.0publishing the wrist sensor
octomapBSD, declared in its package.xml; there is no root LICENSE filethe occupancy map MoveIt uses for unknown obstacles
ur_robot_driverBSD-3the Universal Robots driver, with an osx-arm64 RoboStack build
franka_ros2Apache-2.0the Franka driver. Its example controllers include joint and Cartesian impedance, which is the practical route to compliance on that arm
isaac_ros_cumotionNVIDIA Isaac ROS Software LicenseGPU planning — proprietary, see section 1.4

One thing worth stating because it is a category error people make. MoveIt's perception pipeline builds an octomap so the planner can avoid unknown obstacles. It is not a measuring tool and was never meant to be. The perception area says the same thing, and the mistake in this direction is the mirror image: using the octomap as the model of the part you are about to grasp, rather than as the model of the things you must not hit.

5. The comparison grids#

Everything in one place.

5.1 The five kinds of move#

Read this as a decision table: the four middle columns are what each kind of move demands of you, and the last says where it is covered properly.

KindDeterministicNeeds a world modelNeeds force sensingNeeds a fast sensor loopWhere it is covered
free moveno, for samplers; yes, for optimisersyesnonoplanning, sections 2 and 3
straight lineyesonly if you check collisionsnonoplanning, section 5
guardedyesnoyesnocontrol, section 5
compliantyesnoyes, or joint torquenocontrol, section 4
servoednononoyes, 30 Hz or bettercontrol, section 6

5.2 Choosing a planner#

Speed is an order of magnitude on ordinary hardware rather than a benchmark figure, because the benchmark figure depends on a card you probably do not have.

ApproachSame answer every runFinds awkward routesPath qualityTypical timeLicence
RRT-Connectnovery goodpoor, needs smoothingtens of ms, with a long tailBSD-3
RRT* and PRM*novery goodimproves with timehundreds of msBSD-3
CHOMP, STOMPyespoor — local minimagoodtens to hundreds of msBSD-3
TrajOptyesmoderatevery goodtens of msmixed, marked per file
Pilz PTP, LIN, CIRCyesnone — it does not searchexactly what you specifiedsub-millisecondBSD-3
Cartesian interpolationyesnonea line, or part of onemillisecondsBSD-3
cuRoboclose to, with a warm startgoodvery goodaround a millisecondApache-2.0, CUDA only
a learned motion policynoas good as its training setgoodfixed, and smallMIT for Motion Policy Networks

5.3 Choosing a controller#

Read this as: what you hand the controller, what hardware that needs, and what it is for. The licence column is the one that decides whether you may ship it.

ApproachWhat you commandNeedsSuitsLicence
joint trajectoryjoint positions over timenothing extraexecuting a planApache-2.0
Cartesian motiona tool pose or twista Jacobian, and singularity handlingstraight lines, jogging, servoingBSD-3
admittancea stiffness, measured through a sensora wrist force-torque sensorinsertion, hand guiding, contact on a position-controlled armApache-2.0
impedancea stiffness, at the jointjoint torque sensing or controlfast contact, on arms that support itvendor, or Apache-2.0 via franka_ros2
explicit forcea force along chosen axesa sensor, or a compliant flangepolishing, deburring, pressingvendor, mostly
visual servoa target in image or pose terms30 Hz perceptionaligning to something that movedGPL-2.0 for ViSP
model predictivea cost and constraints over a horizona dynamics model and a solverconstraints over time, moving targetsBSD-2 or BSD-3
a learned policynothing — it emits the commanda dataset, and a controller underneathcontact and appearance-driven tasksMIT to non-commercial; check the weights

5.4 The silent failures, in one place#

Every failure in this area that produces no error message, with the setting or the assumption it hides behind and the section that works it out.

The failureWhere it hidesCovered in
a straight line whose ends are reachable and whose middle is notnothing checks the path, only the posesreaching, section 2
"unreachable" meaning "not found in 50 ms"kinematics_solver_timeout, default 0.05reaching, section 8.1
joint limits narrowed in the description filethe UR5e elbow, halved on purposereaching, section 4
an early grasp choice making a later place impossibleeach step plans successfullyreaching, section 5
a partial Cartesian path executed as if completethe returned fraction, ignoredplanning, section 5
zero collision paddingdefault_robot_padding, default 0.0planning, section 7.1
a path through a thin obstaclelongest_valid_segment_fraction, default 0.01planning, section 7.2
a held object not attached to the arm modelnothing reports itplanning, section 7.3
a trajectory controller that checks nothingconstraints.trajectory and constraints.goal, both 0.0control, section 3
a guarded move on a sensor that cannot see the eventthe arm simply keeps goingcontrol, section 5
a real-time library making a network callRuckig's intermediate waypointssection 1.3
weights licensed differently from the codeGR00T N1.5, openpilearned motion, section 2.1

Back to the overview.