Skip to main content

10.2.0

· 60 min read

Major Features​

Camera Calibration Objectives​

You can now calibrate a camera against your robot with four Objectives:

  • Calibrate Eye In Hand Camera for a wrist-mounted camera
  • Calibrate Eye To Hand Camera for a fixed one
  • Calibrate Multiple Cameras for any mix of both in a single motion pass
  • Calibrate Camera Intrinsics for the camera's own lens model

You can also print a ChArUco board from the new board editor and let Generate Calibration Waypoints plan the views; the robot then moves through them, detects the board, solves the calibration, warns when the fit is poor, and reports the camera pose. See the camera calibration guide.

Collision Checking Controls for RRT Planning​

Collision checking in the ProRRT planning Behaviors is now tuned from a single collision-check setting. An opt-in sanity check re-validates every planned trajectory, replans from a new seed when it finds a collision, and fails naming the colliding bodies rather than returning a trajectory that tunnels through an obstacle; on the collision-tunneling benchmark it cuts residual tunneling roughly 7 to 12 times. The same setting sets the checking resolution in workspace terms, so joints that sweep the robot through large arcs are checked more finely, and pads both the robot's links and the world's objects. Every control is off by default, so existing plans are unchanged until you turn one on, as motion planning best practices describes. Core

Mimic Joints Across Planning and Control​

Planning groups that contain mimic joints, such as a linkage-driven gripper, now work end to end. Motion planning, inverse kinematics seeding, and per-joint planning costs all accept them: the mimic joints follow the joint they are geared to, only the actively driven joints are commanded, and the Joint Control tab no longer offers to jog a joint that cannot move on its own. The Runtime also checks at load time that no mimic joint can be driven past its own position, velocity, acceleration, or jerk limits, and refuses to start with an error naming the joint and the fix rather than running a robot model whose mimic joint can exceed its own limits. Core

Train VLA Policies in the Cloud from the Desktop App​

The Trainer UI sidebar can now send a dataset to RunPod and bring back a trained Vision-Language-Action (VLA) policy without leaving the Desktop App. Store the RunPod credentials once, review the paid resources before they start, watch training progress live, and publish the checkpoint when it finishes; Trainer verifies that the cloud resources are cleaned up and configures the result for ExecutePolicy. Each checkpoint carries a policy manifest recording the frame rate, robot-state width, camera mapping, and base model and dataset revisions it was trained with, so it can be configured from its Hugging Face revision alone, as Train a VLA Policy with Trainer shows.

Evaluate a Policy Before You Trust It​

The Trainer UI sidebar's new Evaluate tab runs a task Objective for a fixed number of trials and reports how many passed, with the range the pass rate would likely fall in over many more trials. Supply a reset Objective to set up each trial and a scoring Objective to judge it, and the same loop that runs from the Desktop App runs from a script. Evaluate a VLA Policy explains how trials are scored and how to write both Objectives.

Import and Review LeRobot Datasets​

Datasets published on Hugging Face can now be brought into the Trainer UI sidebar and judged episode by episode before they shape a policy. Play each episode with its Dataset Signals and matched camera views, keep or reject it, and import the kept and unreviewed episodes for training. The reverse direction is covered too: a Prepare and Upload workflow validates a LeRobot dataset and publishes it to Hugging Face Hub, with add-only or local-override updates and reusable credentials.

Qualcomm Dragonwing NPU Acceleration​

MoveIt Pro now runs Open Neural Network Exchange (ONNX) models on the Hexagon neural processing unit (NPU) of Qualcomm Dragonwing processors. On a Snapdragon host the moveit_pro command selects the Qualcomm-enabled ARM64 image and offers to install the packages the NPU needs. Models exported from Qualcomm AI Hub for the Qualcomm AI Engine Direct runtime run on the NPU automatically, and the shipped segmentation Behaviors accept Segment Anything Model (SAM3 and SAM2) exports from AI Hub. Configure Qualcomm Dragonwing takes a board from flashing Ubuntu to a connected Desktop App.

Stereo Visual Odometry​

A robot that cannot trust its wheel odometry can now estimate its own motion from a synchronized stereo camera pair. Stereo visual odometry publishes the estimate as standard ROS odometry, runs on the CPU with the ALIKED and LightGlue feature models, and is started, reset, stopped, and queried from a Behavior Tree or a service. The lunar_sim reference application demonstrates it on a Husky A300.

A Path-Traced Camera Renderer for the Simulator​

Simulated cameras can now render with Nyx, an optional path-traced renderer, publishing alongside or in place of the MuJoCo camera topics. It runs on amd64 NVIDIA and AMD ROCm images once its runtime is installed, and nothing changes until a configuration that supports it opts in.

A Sidebar for Every 3D Visualizer Display​

The 3D Visualizer has a sidebar that lists every display with its settings and a search box, so a display's options are found by name instead of hunted through menus. Open it from the navbar, the V key, or the View menu, where each display row now links into the sidebar for its settings. Point Cloud Snapshots gain an adjustable point size there, remembered across reloads.

The 3D Visualizer now shows a mobile base's navigation stack at work, not only its global plan. Live laser scans overlay the navigation map, with the point size and color of each sensor source adjustable. The Nav2 local plan and the controller's candidate trajectories are drawn alongside the global plan, each with its own toggle under Navigation in the View menu, with candidate-trajectory sources discovered automatically and off by default. The velocity the controller is commanding appears as an arrow for the linear velocity and an arc for the yaw rate, with both values labeled in the corner of the pane, so you can see what the base was told to do at the moment it did it.

Approve Planned Trajectories Before the Robot Moves​

A new Require approval before every robot motion setting previews each planned trajectory for approval before the robot follows it, without editing any Behavior Tree, including trajectories in Objectives you did not write. Turning it on asks for confirmation and explains what the approval gate covers: Behaviors that stream controller commands and teleoperation jogging are not gated, and it is a debugging aid, not a safety interlock.

Motion Speed Controls for Objectives and Teleoperation​

Objective motion speed on the Joint Trajectory Admittance Controller is set from the Motion Speed group in Settings, with the current percentage beside the slider and an indicator in the title bar whenever the robot is set below full speed, so a slowed robot is easy to spot, as controlling end effector speed describes. Teleoperation has its own speed, shown below the mode tabs, with an independent setting for each mode.

Enhancements​

Integrated AI Models and GPU Acceleration​

  • Trainer's recording controls can save an episode and continue recording, save and stop, or stop and discard the current episode. In the Desktop App, Until I Stop mode has its own reset delay, which defaults to no pause between episodes; a direct /trainer/start_recording call gets the same result by sending reset_time_s: 0, and a call that omits the field keeps the service's 5-second default. In Until I Stop mode, a Quest recording session ends after its episode is saved, so each Quest save produces one episode.
  • Trainer's LeRobot export stores camera streams as H.264 MP4 video again instead of PNG frames, so converted datasets are far smaller and load as standard LeRobot video datasets. Converting a recording whose camera topic holds H.264 or H.265 video packets now fails with an error naming the camera; record cameras as sensor_msgs/Image or sensor_msgs/CompressedImage.
  • A LeRobot pi0.5 fine-tuned checkpoint can be exported to a MoveIt Pro model bundle for LibTorch, ONNX Runtime, or both with the pi05-export command, or with the export-model workspace skill after training with train-model. The bundle carries the checkpoint's normalization statistics, camera mapping, joint order, and tokenizer, and a checkpoint with missing or conflicting facts is refused. The new Pi05 policy in moveit_pro_ml loads such a bundle and predicts action chunks on LibTorch from camera frames, joint state, and a task prompt.
  • NVIDIA CUDA images now include LibTorch for native TorchScript inference. Select the LibTorch runtime and CUDA device through model configuration; development images retain the headers for custom C++ integrations.
  • The NVIDIA CUDA image now ships ONNX Runtime 1.30.0, which loads the SAM3 models on the CPU when CUDA is unavailable.
  • GetMasks2DFromExemplar and GetMasks2DFromPointQuery run Qualcomm AI Hub SAM3 and SAM2 exports on the Hexagon NPU. Point the Behavior's model_bundle_manifest port at a bundle manifest for the export, as Configure Qualcomm Dragonwing describes. SAM3 exports take text prompts only, and SAM2 exports take at most two foreground points.
  • MoveIt Pro automatically configures supported AMD GPUs for VLA inference without requiring the AMD Container Toolkit.
  • Trainer's Record and Prepare tabs have a copy button beside the training data path, and the Training panel no longer scrolls sideways when a recorded dataset's path is too long to fit.

New Behaviors and Libraries​

  • DetectCharucoBoard, RecordCalibrationSample, ResetCalibrationSamplesVector, SolveEyeInHandCalibration, and SolveEyeToHandCalibration calibrate the pose of a camera mounted on the robot (eye-in-hand) or fixed in the workspace (eye-to-hand) from a ChArUco board.
  • RefineCalibrationBundleAdjustment and GetRefinedCameraCalibration jointly refine all camera calibrations by minimizing reprojection error over the recorded board corners, and report the fit before and after refinement.
  • GenerateCalibrationViews generates a ring of views around the current end effector pose that tilt about the board and shift across the image, and solves a collision-free joint state for each one.
  • CalibrateCameraIntrinsics calibrates a camera's focal lengths, principal point, and distortion from collected calibration samples and checks the intrinsics the camera publishes against the result. It takes the samples, the camera's name, and its CameraInfo, and outputs the calibrated CameraInfo.
  • GetWaypointNames retrieves the names of saved waypoints that start with a given prefix.
  • AccumulateSurfaceCoverage and RecordSurfaceCoverage paint the part of a target surface a tool has already treated and accumulate it across sweeps. Place AccumulateSurfaceCoverage beside the motion in a Parallel.
  • CropPosesToPointCloudFootprint keeps only the poses lying over the area a point cloud covers, and ExtractDominantPlaneFromPointCloud keeps only the points on a cloud's largest flat surface, so a path built on it follows that surface.
  • WaitForConditionFromGeminiQuery asks Gemini a yes/no question about the latest image from a camera topic and succeeds on the first yes. Run it next to a long-running Behavior such as ExecutePolicy under a Parallel to end that Behavior when the model judges the task done. It fails when it waits longer than message_timeout_sec for a new image or keeps failing calls for that long, and it needs GOOGLE_GEMINI_API_KEY and network access.
  • WaitForUserDecision shows its prompt text at the top of the Desktop App view, beside the other approval prompts, with an approve_label button that returns SUCCESS and a reject_label button that returns FAILURE, so an Objective can branch on the user's answer. It fails with an error when no Desktop App is connected or nobody answers within timeout_sec seconds.
  • PublishGhostRobotState publishes a robot state for the 3D Visualizer to render as a ghost robot, and clears it again when its hide port is set.
  • GetLaserScan, GetOccupancyGrid, ScanMatchResidual, and ReinterpretPoseFrame join the navigation Behaviors. With them an Objective can refine a particle-filter localizer's estimate without moving the robot and accept it only if the live laser scan fits the map, as the Nav2 guide shows in hangar_sim.
  • CallEmptyService calls a std_srvs/srv/Empty service.
  • StartStereoVisualOdometry, StopStereoVisualOdometry, ResetStereoVisualOdometry, and GetStereoVisualOdometryStatus control stereo visual odometry from a Behavior Tree. The ControlStereoVisualOdometry service does the same from outside one, and setting the read-only autostart parameter or launch argument to true starts tracking as the component loads.
  • SetMujocoFreeBodyPoses moves objects that have a free joint in the MoveIt Pro Simulator to the poses in poses, one per name in body_names, all in one simulation step. Each pose can be in any frame that connects to mj_world in the transform (TF) tree.
  • IsBlackboardVariableSet returns SUCCESS when a blackboard variable has been written to and FAILURE when it is unset, so an Objective can branch on whether a value exists.
  • Finally is a new control node for guaranteed cleanup. Its second child runs after the first child succeeds, fails, or throws, and when the Objective is stopped, for example to re-enable a collision rule after an operation that may fail. When an Objective is stopped, the cleanup branch runs to completion, motion and gripper commands included, for up to halt_timeout_msec milliseconds (10000 by default).

Behavior and Library Improvements​

  • ExecutePolicy now pauses at rest and resumes when the policy's next action chunk arrives late, instead of failing the run. It warns once per run when pausing begins and reports the pause count and total paused time at the end. The total_action_steps budget now counts executed policy motion only, so neither the wait for the first chunk nor a pause consumes it, and a run takes correspondingly longer in wall time.
  • PlanToJointGoal now names the offending joint, the value it was given, the limit it violated, and by how much when a joint goal is outside limits, in the joint's own units, and says whether that limit came from the robot model or from a joint range constraint.
  • PlanToJointGoal, SetupMTCPlanToRobotState, SetupMTCConnectWithProRRT, SetupMTCPlanToPose, PoseJog, and JointJog can pad world objects: set override_scene_world_padding: true and world_padding in meters in their collision_check_params input port, or use the port's field editor. Octree and plane shapes cannot be padded, so world padding adds no margin around an octomap.
  • PoseJog and JointJog accept the same collision_check_params input port as the ProRRT planning Behaviors for their collision-check padding, with their standalone link_padding port deprecated the same way. The teleoperation Objective's padding inputs now cover PoseJog as well as its planning Subtrees.
  • PlanToJointGoal can be subclassed: pass an ExtraValidator to its constructor to reject joint-space configurations the built-in collision and constraint checks accept, and inherit the rest of the Behavior unchanged.
  • TransformPoseFrame, CalculatePoseOffset, PlanCartesianPath, and the other core pose-consuming Behaviors now resolve a PoseStamped input at the pose's own timestamp, so a pose captured by a moving camera keeps its original intent; a timestamp too old for the transform buffer falls back to the latest transform and reports it instead of failing.
  • GenerateSurfaceCoveragePath can now follow a scanned surface. Wire a point cloud to its new point_cloud port and set projection_mode to SURFACE: the region is read as a 3D selection box (its +Z axis toward the tool, its X axis along the sweep), the raster is projected onto the points inside it, and the path keeps the standoff from the measured surface with the tool held within orientation_cap of the box axis. The new orientation_offset port turns the tool about the waypoint's own axes in either mode. Without a cloud the Behavior sweeps the region's top face as before; it is now asynchronous, returning RUNNING while the path is generated.
  • GenerateSurfaceCoveragePath now takes its raster layout from a single raster_layout port of the new RasterLayout message (line spacing, point spacing, margin, and lines along the region X or Y axis), with a Desktop App dialog that previews the raster, its waypoint count, and path length over the node's region before you run the Objective. The line_spacing, point_spacing, and margin ports still work but are deprecated; move their values into raster_layout.
  • GetOrientedBoundingBoxFromPointCloud can now take its X and Y axes from the reference pose with align_xy_to_reference, for flat regions whose own principal axes are meaningless.
  • GetPoseFromPixelCoords has a new optional camera_info input that takes the clicked image's CameraInfo. Set it when the point cloud comes from a different camera than the image, so the pose lands on the point you clicked.
  • GetPoints2DFromGeminiQuery now defaults to the gemini-robotics-er-2-preview model, because Google no longer serves gemini-2.5-flash to new API keys, and a failed Gemini request now reports Google's error message instead of the raw JSON body.
  • CalibrateCameraPose is deprecated in favor of the Calibrate Eye To Hand Camera Objective, which calibrates a fixed camera from a printed ChArUco board mounted on the arm instead of the AprilTag calibration tool. The Behavior still works but will be removed in a future version; the camera calibration guide covers the replacement workflow.
  • SetInitialPose takes an optional pose to seed the localizer at, such as a pose an operator places.
  • GetOdom has a new odometry_twist output port. It holds the odometry twist as a TwistStamped, stamped with the odometry time and expressed in the odometry child_frame_id.
  • AddURDF can now display a URDF's visual geometry as well as adding its collision geometry to the planning scene. It is off by default; set show_visual_geometry to true and the object renders as authored, with its own meshes and materials, alongside the collision shapes. Planning and collision checking still use <collision> geometry only.
  • Move to Joint State, Move to Named Waypoint, and Move to Named Waypoint (JTC) have a require_user_approval port. Set it to true to preview the planned trajectory and wait for approval before the robot moves, as Move to Cartesian Pose already does.
  • ComputeInverseKinematics, SolveIKQueries, ValidateTrajectory, ComputeSignedDistanceField, GenerateVacuumGraspPoses, and GenerateCalibrationViews now report why a planning scene message could not be applied instead of a generic "Error setting the planning scene".
  • BreakpointSubscriber now derives a topic of its own when breakpoint_topic is left empty, and reports that topic in the topic field of /breakpoint_encountered. Custom tooling that compares that field against /moveit_pro_breakpoint should treat it as an opaque value to publish back to instead.
  • JointTrajectoryAdmittanceController reports reference velocities and accelerations on its controller_state topic in wall-clock time when time_scale_percentage is below 100, and its admittance response adds to the wall-clock reference velocity.

Simulation Improvements​

  • The MoveIt Pro Simulator now publishes its full state vector on /mujoco/qpos_stamped, with the model's kinematic mapping on /mujoco/qpos_schema, so external tools can mirror bodies such as cables and hoses that were previously visible only inside the simulation. Set qpos_publish_rate to change the rate or to zero to disable it; publishing is on by default at 60 Hz.
  • A camera-based 3D lidar in the MoveIt Pro Simulator can add sensor noise. Set range_noise_stddev, range_noise_mean, dropout_probability, and noise_seed in its URDF <sensor> block, as the image-based lidar section describes.
  • A camera-based 3D lidar in the MoveIt Pro Simulator can publish a LaserScan instead of, or as well as, its point cloud. Set lidar_output to scan or both in its URDF <sensor> block, with scan_topic and scan_row to choose the topic and the ring. The scan is published in a <camera_name>_ROS frame the Simulator broadcasts, so it can replace a node that flattens the cloud into a LaserScan. If your configuration already publishes a static <camera_name>_ROS frame for such a node, remove it when you turn on the scan.
  • A MuJoCo camera's <sensor> block accepts color_enabled; set it to false to keep an RGB-D camera's depth image and point cloud while leaving its color and camera_info topics to another publisher, as Create MoveIt Pro Simulator Models describes.

Discovery and Security​

  • A deployment can point at an inference server on another machine over verified HTTPS, as endpoint authentication describes. moveit_pro inference-key prints an inference-only key with no access to the Runtime's other endpoints, and the inference server that moveit_pro run starts now receives it as MOVEIT_INFERENCE_KEY, which the vla_sim example's server and adapter use. A custom inference server should require it as its bearer token, a custom adapter should send it, and a deployment started without the moveit_pro command must set it. Passing MOVEIT_FRONTEND_KEY to the inference server is deprecated and will be removed in a future release. With an HTTPS INFER_URL, Trainer's Configure for ExecutePolicy verifies a checkpoint and reports its ExecutePolicy settings and the serving settings to set on the inference host.
  • MoveIt Pro Runtime logs now correlate Desktop App Objective activity with the client IP observed by the WebSocket bridge.

Misc User Interface Improvements​

  • A failed motion plan's alert now offers Inspect failed plan in Task Constructor Debugger, which opens the debugger on the stage where planning ran out of solutions. This also fixes the Task Constructor Debugger's planning-iteration history, which previously stayed empty, and with it the debugger icon shown on a planning Behavior in the Behavior Tree view.
  • JSON files saved by SaveMTCTaskInspection can be imported into the Task Constructor Debugger to inspect saved planning stages, failures, and trajectories.
  • When a planning Behavior refuses a pose for collision, the 3D Visualizer now draws the collision geometry inflated by that check's link padding over the rejected pose, so the clearance the check demanded is visible instead of appearing as empty space around the contact points. The rejected robot configuration is also drawn when a joint goal is refused for being outside limits or outside an orientation constraint tolerance, as it already was for a goal in collision.
  • Breakpoints can now be set from the Behavior Tree node actions, and each one is resumed on its own instead of continuing every breakpoint at once.
  • The Ports panel lists deprecated ports after active ports under a labeled divider, so current ports are easier to find on Behaviors that still carry deprecated ones, and a port value can be returned to unset from the Edit Menu, so it falls back to its default instead of being authored as an empty string; an unset port is marked as such with the default it will use.
  • The Alert Sidebar and its settings were reworked. Alerts show the time they arrived, down to the second, with the date on hover. Alert Settings sets severities separately for toast messages and the Alert Sidebar, replacing the single Toast Notifications switch: toasts are limited to errors by default, the sidebar keeps listing errors, warnings, and info, the bell icon counts whatever no longer appears as a toast, and the two severity lists sit side by side with the arrow keys moving between them. Editor alerts now appear in the Alert Sidebar from the first launch, alongside Runtime alerts, instead of staying hidden until an Objective is opened in the editor; deselect either source under Alert Settings. Upgrading keeps a deselected Runtime source but restores Editor once.
  • Camera panes can overlay the robot and 3D scene on the camera image using the camera's calibration, with adjustable image opacity, so a calibration can be checked by eye.
  • The 3D Visualizer draws camera frusta, with live and recorded camera images positioned in the scene and per-camera controls in the sidebar.
  • Named visualization configurations can be saved and loaded from View, then Configuration, in a 3D Visualization pane to switch pane layouts, display settings, TF selections, and individual robot-link visibility. Terminal panes restore through normal startup and respect the Runtime's host-shell permissions.
  • The Particle Filter overlay under Navigation in the View menu is now enabled by default for every discovered particle-cloud topic, so a mobile base shows its localization without being configured for it. Disable a source to opt out; the choice is saved in your browser. Upgrading to 10.2 ignores Particle Filter visibility choices saved on an earlier release, so a source you had disabled comes back enabled once.
  • The Commanded Velocity overlay is enabled under Navigation in the View menu. The navigation overlays' topics are Desktop App settings: nav2LocalPlanTopic for the Nav2 local plan, nav2CmdVelTopic (default /cmd_vel) for the Commanded Velocity overlay, and nav2CmdVelFrame for the frame of a publisher that sends an unstamped geometry_msgs/Twist.
  • The 3D Visualizer renders a translucent ghost robot from moveit_msgs/DisplayRobotState messages published on /display_robot_state, so an Objective can show a suggested robot configuration without planning a trajectory for it. Toggle it under View, Display, Robot - Display State.
  • A Surface Coverage layer in the 3D Visualizer, with a legend and a visibility toggle in the View menu, fills in live the part of a target surface a tool has treated as it sweeps, recorded from where the tool actually went rather than where it was asked to go, and the history survives the Objective run that produced it. GenerateSurfaceCoveragePath gained a preview dialog that shows the raster, waypoint count, and path length before the Objective runs.
  • An optional TF label overlay keeps frame names readable through robot and scene geometry while preserving normal axis occlusion.
  • The 3D Visualizer's measurement tool, now Measure distance and coordinates, reports the position under the cursor in the active fixed frame, in the readout and on a label beside the point, and snaps to the point a point cloud actually holds, so you can read a sensor coordinate without placing an object there.
  • Each point cloud source in the 3D Visualizer sidebar offers a Reduced Stream choice. It streams that source at about a tenth of the bandwidth for a MoveIt Pro Desktop App on a remote link, while other viewers keep full quality.
  • Robot link colors and transparency can be changed in the Desktop App by setting PlanningScene.object_colors IDs to URDF link names. Use alpha zero to hide a link's visuals without hiding its children or disabling collision checking, as interacting with the planning scene describes.
  • The Pose teleoperation settings gained a Jog Collision Checking toggle, so an operator can jog the end-effector out of a collision without leaving the manual-control panel.
  • A persistent GPU Status pane shows the configured GPU deployment settings separately from the observed simulation, ML inference, device, driver, renderer, and execution-provider outcomes, and a read-only GPU status command and endpoint collect the same diagnostics for support.
  • The Desktop App can start a MoveIt Pro Runtime on the computer it is running on (Linux only). Click the Quickstart tab on the connection screen, pick an example robot configuration, and click Launch; the app shows the Runtime's log, connects when it is ready, and shuts it down again with Stop. Quickstart opens first when there are no saved connections and no running Runtimes, as Connect with the MoveIt Pro Desktop App shows.
  • The Desktop App can be locked to Operator mode, which runs, stops, and resets Objectives but hides editing, or to Read-Only mode, which only watches, from Desktop App Settings on the connection screen. A password you create protects the setting, and both modes stay off until you turn one on.
  • The Desktop App opens with a short introduction on first run, recommending PickNik's free live monthly training course, integration services, and tutorials, with a "Don't show me this again" checkbox.
  • The Desktop App is more responsive while following active nodes in expanded Behavior Trees.
  • The Desktop App window title names the connected Runtime's version when it differs from the Desktop App's.

Reference Application Changes​

  • so101_base_config and so101_sim are new configurations for the SO-101 arm: a mock-hardware simulation with joint and pose teleoperation, the XLeRobot fin gripper in place of the stock jaws, a driver for the physical arm over the Feetech STS3215 servo bus with torque that follows the ros2_control lifecycle, and leader-arm mirroring and calibration tooling.
  • rebot_bench_base_config and rebot_bench_sim are new configurations for the reBot B601-RS bench, with a RobStride hardware backend and a MuJoCo twin of the bench.
  • lunar_sim was rebuilt as a Husky A300 lunar simulation: a cratered heightfield with non-repeating regolith, a star field and far horizon, moon base landmarks and boulders, A300 lidars, a mast scene camera, and an arch-mounted OAK-D Pro whose stereo renders feed stereo visual odometry. The new lunar_sim_behaviors package adds TeleoperateBase, which drives the base over cmd_vel during teleoperation.
  • hangar_sim now navigates on the fused localization estimate instead of simulation ground truth, feeds both lidar scans to AMCL (Adaptive Monte Carlo Localization) without merging them, refines localization in place with a fit-to-map gate, publishes and visualizes the MPPI (Model Predictive Path Integral) local plan, shows the commanded velocity overlay by default, re-seeds AMCL after a simulation teleport, and ports the image-based lidar.
  • lab_sim gained surface coverage demo Objectives, a closed-loop AprilTag counterpart to the 3 Waypoints Pick and Place demo, and support for the Nyx path-traced camera renderer.
  • vla_sim gained a scripted red-block pick demonstration for data collection, Objectives that end the policy run once the cubes are stacked, Objectives for evaluating the cube-stacking policy, verified HTTPS for remote inference with the inference key, serving on the host GPU target (including ROCm), and /health and /status endpoints that report the serving precision and loaded configuration.
  • hand_eye_calibration_sim gained a Move to Home Objective, bigger calibration boards, an intrinsic calibration start pose, and a listing in the launcher.
  • factory_sim configures its bin poses in YAML and derives the rim, crop, and drop poses from them, and times the bracket pick-and-place cycle with the Stopwatch Behaviors.
  • kitchen_sim and dual_arm_sim are standalone configurations built on a vendored franka_description 2.9.0; franka_base_config was removed, and both packages attribute their third-party MuJoCo models and meshes.
  • space_satellite_sim_camera_cal was removed; the hand_eye_calibration_sim configuration and the Calibrate Eye To Hand Camera Objective replace it.
  • All configurations migrated their deprecated link_padding ports to collision_check_params, use the 10.2 Runtime launch entry point, and set goal tolerances that satisfy the Joint Trajectory Admittance Controller's enforced goal tolerance.
  • kinova_sim, in moveit_pro_kinova_configs, lowers the Robotiq MuJoCo actuator damping and sets stall_velocity_threshold so blocked gripper closes settle and succeed, and the Robotiq mock hardware no longer declares command interfaces on mimic joints.

Documentation Improvements​

  • The C++ API reference is now part of the documentation site, sharing its navigation and search instead of living on a separate Doxygen site.
  • Added a Vision Language Model (VLM) Prompting Best Practices guide covering coordinate conventions, hallucination control, reference images, and evaluating prompt changes when using a VLM from a Behavior Tree.
  • Added a Whole-Body Motion concept page describing how MoveIt Pro represents and executes coordinated mobile-base and arm motion, and which base types that model supports.
  • Added Visualize a Ghost Robot, covering the topic, the Behavior, and which message fields are rendered.
  • Added End a Policy Run on a Signal, a guide to ending an ExecutePolicy run as soon as the task is done, with a cube-pose check and a Gemini detector as vla_sim examples.
  • Added Train a VLA Policy with Trainer and Evaluate a VLA Policy, covering cloud training from Trainer and how each evaluation trial is scored, how to write a reset Objective and a scoring Objective, and how to run evaluations from a script.
  • Added a Localization Tuning guide for tuning and measuring a mobile base's AMCL and odometry localization stack.
  • Added a Mobile Base Support page that summarizes the localization, mapping, navigation, sensors, and drive types MoveIt Pro supports for mobile bases.
  • Added Require Approval for All Motion, covering the approval setting and the require_user_approval port.
  • Added Collect a Support Bundle, covering collection levels, sensitive artifacts, size limits, archive review, and manual transfer.
  • Added Configure Qualcomm Dragonwing, a step-by-step guide for running the MoveIt Pro Runtime on Qualcomm Dragonwing boards, from flashing Ubuntu through NPU package setup to a connected Desktop App.

Other Improvements​

  • moveit_pro configure now asks its questions on one screen when run in a terminal. The user workspace and robot configuration are chosen from a list of what is on disk, answered questions stay visible, ← or backspace goes back to change one, and typing on a list enters a value it does not offer. The GPU validation rows update as each check finishes.
  • moveit_pro support-bundle, and Generate Support Bundle in Desktop App Settings, collect a diagnostic archive with selectable categories and collection levels, a manifest to review, and credential scrubbing, including when the Runtime is stopped. Collect a Support Bundle describes what each level gathers.
  • Each moveit_pro run now saves its console output and per-service exit records, including out-of-memory status, under ~/.ros/log_moveit_pro/moveit_pro_runs/<run>/ (under MOVEIT_HOST_LOG_DIR when set), with moveit_pro_runs/latest pointing at the most recent run, so a later command or relaunch no longer overwrites the output of a failed run. Each run keeps up to 1 GiB of console output, the start of the run plus its newest 64 MiB, and old runs are removed to keep the directory under 10 GiB and 100 runs; records are retained for MOVEIT_DIAGNOSTICS_RETENTION_DAYS, 14 by default. ~/.config/moveit_pro/last_moveit_pro_run.log now stops at 1 GiB.
  • The MoveIt Pro Runtime keeps a durable record of every failed Objective on the robot host, in the run directory's decision_log.jsonl, with the execution ID, Objective name, failure class, reason, and the Behavior error messages, and the Desktop App shows that retained failure history, so support can read why an Objective failed after the Desktop App is closed or the stack restarts.
  • Crashes now leave a trace in the console log: a Python process in a MoveIt Pro container that dies on a fatal signal such as a segmentation fault prints its Python traceback (set PYTHONFAULTHANDLER= to an empty value in the container environment to turn this off), and a crash in a Runtime composable node prints a stack trace in the same format as crashes in move_group and the Objective server.
  • The Model Context Protocol (MCP) server can now create and update Objectives, and complete custom Behavior packages with their build, plugin, and test wiring, from shipped authoring guidance, with validated and revision-checked edits that take effect without a workspace build or Runtime restart. It finds loaded Behaviors through compact, searchable results, requests port details only for the nodes you need, and searches Objectives by name, description, and category.
  • Host-user MCP sessions can start and cancel Objectives by goal ID, capture camera snapshots with camera poses and depth-backed point measurements (with optional Gemini scene inspection), and save named SSH target profiles that generate compact remote client entries. Policies are optional restrictions, and approvals follow the MCP client's settings.
  • moveit_pro mcp serve no longer needs --workspace or --config-package. It binds the running Runtime, or the configured workspace and config package when none is running, so claude mcp add --scope user moveit-pro -- moveit_pro mcp serve and codex mcp add moveit-pro -- moveit_pro mcp serve connect an agent to whichever Runtime you launch; with several Runtimes running, pass --instance <name> (--instance default for the unnamed deployment) or start the client inside that Runtime's workspace. moveit_pro mcp session list shows the MCP sessions on a host, which client and target each belongs to, and whether its launcher is still running, and an MCP button in the Desktop App's Host and AI Assistant terminals copies a ready-made Claude Code or Codex connection command for the connected Runtime.
  • The MOVEIT_WEBRTC_BITRATE and MOVEIT_WEBRTC_MAX_RESOLUTION Runtime settings lower the bandwidth camera panes use on constrained networks. Frames larger than the configured resolution are scaled down with their aspect ratio kept, and the 3D camera overlay keeps working on scaled streams.
  • Behavior Tree logs (.btlog) now write each node in the explicit <Action ID="..."> form, or Control, Decorator, or Condition, instead of an element named after the node type. Groot2 opens both forms. Update any custom tool that parses the tree XML inside a .btlog file.
  • The moveit_pro command asks you to accept Meta's SAM License before building the moveit_pro_sam3 package, states the field-of-use restriction the license carries, and excludes the package from the build if you decline. The prompt is shown again each time the example workspace is cloned or upgraded, even if you answered before; declining the upgrade, unattended runs, and runs with MOVEIT_ACCEPT_SAM3_LICENSE set keep the current answer, which you can also change with moveit_pro configure --sam3-license accept or moveit_pro configure --sam3-license decline.
  • On Qualcomm Snapdragon hosts missing the FastRPC packages, moveit_pro run offers to install qcom-fastrpc1 and qairt-dsp-binaries instead of only stopping.
  • Build failures now name the command that resumes the interrupted build.

MoveIt Pro Core​

The changes below ship to every MoveIt Pro customer. They are collected here because they also reach MoveIt Pro Core customers, who install the standalone Core archive rather than the full Application Platform. Major Features, bug fixes, and breaking changes that reach Core appear in their own sections, marked with the Core badge.

  • Motion planning now accepts planning groups that contain mimic joints. Inverse kinematics seeds and solutions cover the actively driven joints and mimic joints follow their driving joint, joint costs apply in both optimize_distance inverse kinematics and the motion planner cost ports, with a mimic joint's motion priced through its driving joint's cost, and the /get_planning_groups service reports each group's actively driven joints in a new active_variable_names field, with the existing variable_names field unchanged. A mimic joint's own position limits are not yet enforced during planning; the driving joint's limits and collision checking apply.
  • MoveIt Pro validates mimic joint position, velocity, acceleration, and jerk limits when loading a robot description. If a mimic joint could be driven past its own limits, the Runtime refuses to start with an error naming the mimic joint, its driving joint, the offending ranges, and where to fix them; a joint_limits.yaml that raises a driving joint's velocity above what its mimic joint's limit allows needs a matching entry for the mimic joint. Setting a planning group's position bounds through the C++ or Python API now fails with a descriptive error when the new bounds would let a mimic joint violate its own position limits, instead of silently accepting them.
  • ProRRT planning can validate motions against collisions at a workspace resolution through the opt-in workspace_step planner parameter, also set from the collision_check_params port of the ProRRT planning Behaviors: motions of joints that sweep the robot through large arcs, such as base joints or arms carrying long attached objects, are checked proportionally more finely, roughly halving collision tunneling through thin obstacles at the recommended 0.1 m resolution. The parameter is off by default, so existing motion plans are unchanged until it is set.
  • Link padding on the ProRRT planning Behaviors is now set through collision_check_params (override_scene_link_padding: true with link_padding). Without the override, the planning scene's own padding applies. The standalone link_padding port is deprecated: while set it still takes precedence, and the Behavior logs the migration edit. The shipped motion Objectives keep their default padding of 0.01 m.
  • pro_rrt can pad world objects, scenario captures record the world padding a PlanToJointGoal plan used, and pro_rrt_replay applies it. Captures from earlier releases replay as before.
  • ProRRTPlanner() with no padding argument now inherits the planning scene's link and world padding instead of overriding both to zero; pass 0.0 explicitly to override both to zero as before. It gains use_scene_world_padding(), which returns the planner to the scene's own world padding after an override, and get_link_padding() and get_world_padding(), which report the padding the next plan applies. The constants kDefaultLinkPadding and kDefaultWorldPadding are deprecated in favor of kZeroLinkPadding and kZeroWorldPadding, since unset padding now inherits the scene's value and zero is an explicit override; the old names still work and will be removed in a future release.
  • pro_rrt::planPathToJointGoal and planTrajectoryToJointGoal accept an optional caller-supplied validation function that rejects joint-space configurations the built-in collision and constraint checks would accept, for example a coupled bound over several joints.
  • The Cartesian planning Behaviors (SetupMTCPathIK, SetupMTCCartesianSequence, SetupMTCMoveAlongFrameAxis, SetupMTCCartesianMoveToRobotState, SetupMTCMultiEEFMoveAlongAxis) and the Python PathIK stage and CartesianPlanner now apply the planning scene's link padding to self-collision checks by default, as the ProRRT planner does. In a scene that carries link padding they may now reject poses that bring links close together; call set_pad_self_collisions(False) on the Python stage or planner to leave self-collision checks unpadded as before.
  • The inverse kinematics stage of SetupMTCPlanToPose, SetupMTCCartesianSequence, and SetupMTCBatchPoseIK now applies link padding to self-collision checks by default, as the ProRRT and Cartesian planning Behaviors do, so in a scene that carries link padding, or with a padding override on SetupMTCPlanToPose, these Behaviors may reject goals where two padded robot links touch. No Behavior port turns this off; from the Python API set pad_self_collisions = False on the ComputeIK stage, or call setPadSelfCollisions(false) in C++.
  • The Python CollisionRequest gains pad_environment_collisions and pad_self_collisions, so is_path_in_collision and scene.check_collision callers can choose which collision checks use the padded robot links.
  • RDFLoader::create() and RobotModelLoader::create() return the loaded loader, or the reason the robot description could not be loaded, instead of a null model whose cause is only in the log. The constructors they replace are deprecated and work as before, except that after a failed load RobotModelLoader::getRDFLoader() now returns null rather than a loader holding null documents.
  • Planning-scene collision-object updates now return actionable errors and preserve existing geometry when validation fails. A collision object with a shape that cannot be constructed, an empty id, empty or duplicate subframe names, or a MOVE in an unknown frame is rejected with an error that names the field and a next step, instead of being partially applied, and PlanningScene.apply_collision_object in the Python API raises ValueError with the reason instead of returning silently.
  • PlanningScene::setRobotStateMsg() applies a moveit_msgs::msg::RobotState atomically and returns an error describing why a message could not be applied, and PlanningScene::setRobotState() does the same for a native RobotState. Both setCurrentState() overloads are deprecated in favor of these.
  • PlanningScene gains applyPlanningSceneMsg(), applyFullPlanningSceneMsg(), applyPlanningSceneDiffMsg(), and applyPlanningSceneWorldMsg(), which return the reason for every update in a planning scene message that the scene rejects. The bool methods setPlanningSceneMsg(), setPlanningSceneDiffMsg(), usePlanningSceneMsg(), processPlanningSceneWorldMsg(), and diff(msg) are deprecated and work as before.
  • The signed distance field that ComputeSignedDistanceField builds from a planning scene can now be computed directly from C++ in MoveIt Pro Core, so regression tests and tools that do not run an Objective can build the same field, with conservative primitive and octomap voxelization, bounded resource use, and actionable rejection of unsupported collision geometry.
  • MoveIt Pro now records which hardware source a computer's license is bound to in /opt/moveit_pro/licensing/fingerprint_pin, shared by every user of the computer, instead of each user's data directory. On computers activated by an earlier release, MoveIt Pro copies the existing record there and leaves the original, as Configure Licensing describes.
  • The moveit-pro-license helper ships as a native binary instead of a bundled Python environment, with Debian package (DEB) and Fedora package (RPM) downloads. The DEB replaces the previous package and keeps the moveit_pro_license command.
  • The Runtime reports academic licenses as the ACADEMIC license type in AgentInfo, and the About dialog shows them as "Academic License".

Bug Fixes​

  • Fixed the simulated vacuum gripper reporting a successful grasp when nothing was picked up. The gripper's state now follows the seal the simulation is actually holding, so a close onto an object the cups never sealed against no longer reports success. Because that state is now always derived from the simulation, the user attribute on a suction_cup_ site no longer sets its starting value.
  • Fixed a MuJoCo mobile base configured with base_link_name getting two TF parents, which made its pose flicker. The Simulator now publishes mj_world to the URDF root (or odom_frame), publishes the base's pose only for a floating parent joint, adds a <base link>_ground_truth frame with the true base pose, accepts a base_pose_source hardware parameter (auto, robot_state_publisher, or simulation), and skips any odometry TF broadcast or object frame that would give a frame a second parent. If another node publishes the parent edge of a base with a floating parent joint, set base_pose_source: robot_state_publisher.
  • Fixed a camera-based 3D lidar in the MoveIt Pro Simulator with a single row or column publishing a point cloud of only NaN values, and one with a 360 degree sweep publishing its first beam twice, once at each end of the sweep; its beams are now 360 / columns degrees apart.
  • Fixed RGB-D cameras and camera-based 3D lidars in the MoveIt Pro Simulator reporting a depth at the far clipping distance, instead of NaN, for pixels and beams that hit nothing, in some scenes that do not set <statistic extent> in their MuJoCo model. Objectives that consume the raw point cloud of such a camera, lab_sim's snapshots and segmentation among them, no longer see a wall of points hundreds of meters away.
  • Fixed a rare heap corruption when a PlanningSceneMonitor was destroyed while it was still publishing a planning scene update. Core
  • Fixed an intermittent hang when stopping or restarting PoseJog and shutting down planning scene monitoring. Core
  • Fixed an intermittent hang when destroying motion-planning tasks. Core
  • Fixed a possible crash when the planning scene service reads an octomap during sensor updates. Core
  • Fixed crashes when planning scenes receive malformed collision objects, incompatible robot state data, invalid octomap data, or null required inputs. Core
  • Fixed integer overflow in image, point-cloud, and voxel buffer sizing for large dimensions, and unsafe virtual dispatch when constructing a distance field from an octree. Core
  • Fixed PlanningScene robot state message application so that a message with an invalid joint value, an unknown joint, an unavailable transform, or an invalid attached object is rejected as a whole, without partially changing the planning scene. setPlanningSceneMsg and setPlanningSceneDiffMsg now return false when the robot state of the message is rejected, and a scene message without a robot state keeps the current one. Attachment operations in one message must not depend on each other: a detach-all cannot be combined with other attachment operations, and an attachment cannot be posed in the frame of an object changed by the same message. Core
  • Fixed an attachment whose header frame starts with / being posed with the joint values from before the message. Core
  • Fixed collision objects with non-finite or zero-norm poses being accepted; they are now rejected with an error naming the object and the field. Core
  • Fixed invalid octomap replacements so they preserve the last valid planning-scene collision geometry and report actionable errors. Core
  • Fixed collision padding set on the planning scene reverting when a full planning scene message arrived before the monitor published the change. Core
  • Fixed ExecuteMTCSolution overwriting the planning scene's link padding and scale with the values the MoveIt Task Constructor (MTC) task planned with. Core
  • Fixed ExecuteMTCSolution emptying the planning scene's allowed collision matrix and world when executing the debug_solution output of ValidateTrajectory or PlanCartesianPath, including with apply_start_scene enabled.
  • Fixed the MTC ProRRT planning Behaviors discarding the collision padding configured on the planning scene. Planning now uses the scene's link and world padding unless a padding value is set explicitly; an explicit 0.0 still removes it. Core
  • Fixed SetupMTCPlanToPose rejecting goals its own inverse kinematics stage accepted when its link_padding port or collision_check_params overrides the padding. The stage now checks the same padding as the planner. Core
  • Fixed planner crashes when start or goal joint positions contain non-finite values. Core
  • Fixed unnecessary full-turn motions and false trajectory-tolerance failures for independent continuous joints when planning and executing across ±π. Core
  • Fixed lost continuous-joint winding after set_group_position_bounds on a group containing a continuous joint. Position bounds requested for a continuous joint are now ignored with a warning naming the joint, and get_group_position_bounds reports its full [-pi, pi] range; the other joints in the group take their limits as before. Such a joint is now treated as periodic throughout: shortest-angular tolerances in the Joint Trajectory Admittance Controller, start +/- pi sampling in ProRRT, and joint-space MoveRelative rejecting offsets larger than pi rather than wrapping them. Use a bounded revolute joint in the URDF for absolute position limits. Core
  • Fixed /get_joint_limits reporting a continuous joint's URDF position range as [0, 0] with has_position_limits set; continuous joints now report no URDF position limits, so the Joint Monitor no longer draws a degenerate limits bar for them.
  • Fixed backward-planned whole-body trajectories ending with nonzero joint velocities after time parameterization. Core
  • Fixed GeneratePointToPointTrajectory rejecting valid start states for planning groups that contain mimic joints, crashing on planning groups that contain multi-DOF (degree-of-freedom) joints, which it now refuses with an error naming the unsupported group, and ending its trajectories one sample before the requested target state.
  • Fixed GetJointState emitting joint values misaligned with their names for planning groups that contain mimic joints.
  • Fixed ghost robot previews (waypoints, trajectories, gripper) showing mimic joints at stored values instead of the value derived from their driving joint.
  • Fixed ComputeSignedDistanceField reporting success while producing an incomplete or mislocated distance field. It now reports an error when the planning scene holds an octomap that is not at the planning frame origin, when the requested links carry no collision geometry, or when the robot state has not been updated.
  • Fixed MoveIt Pro libraries changing their file names on every patch release, which made user workspaces built on an earlier release fail to start with a cannot open shared object file error. Upgrading to this release needs the one-time clean rebuild listed under Breaking Changes; later patch releases will not. Core
  • Fixed a configure failure in custom Behavior packages declared as project(<name> CXX). Any package depending on MoveIt Pro's Behavior interface previously failed with a missing MPI::MPI_C target, and now builds without needing to enable the C language itself. Core
  • Fixed Behavior libraries in a user workspace being built with code-coverage instrumentation by default, which cost multi-threaded throughput while producing identical results. To collect C++ coverage, copy ~/.colcon/defaults.yaml, add the coverage-gcc mixin, and point COLCON_DEFAULTS_FILE at the copy; passing --mixin coverage-gcc on the command line replaces the configured mixin list rather than extending it, and also drops release. Core
  • Fixed a stream of pytest-cov was not found CMake warnings printed on every moveit_pro build and moveit_pro run. User-workspace builds no longer force Python test coverage on every package; a package now gets coverage only when it declares <test_depend>python3-pytest-cov</test_depend>. To enable it for a whole workspace, copy ~/.colcon/defaults.yaml, add the coverage-pytest mixin, and point COLCON_DEFAULTS_FILE at the copy. Passing --mixin instead does not work, because it replaces the configured list rather than extending it.
  • Fixed the Runtime running code from a Behavior plugin that links stock BehaviorTree.CPP before refusing to start. Such a plugin is now rejected before it loads, and the error names the library chain to rebuild against behaviortree_cpp_picknik.
  • Fixed the MoveIt Pro Runtime image omitting the build-configuration records (/usr/share/doc/<package>/BUILD_FLAGS.txt) of the LGPL (GNU Lesser General Public License) packages PickNik compiles, the records that let you build a binary-compatible replacement.
  • Fixed the dev container started by moveit_pro dev running ros2_control without realtime scheduling; it now carries the same rtprio and memlock limits as the drivers service, and drivers gains an unlimited memlock to match the Real-time Performance troubleshooting guide.
  • Fixed a Stop request being ignored for as long as a Behavior held a tick open, so an Objective can now be stopped while one of its Behaviors is still working.
  • Fixed a Stop that arrived while a motion was still being set up being reported as successful while the robot moved anyway. The trajectory is no longer sent once the Objective has been stopped.
  • Fixed the Objective server staying alive after a heap-corruption crash inside its crash handler; it now exits within 10 seconds so the Runtime shuts down and can be restarted.
  • Fixed ambiguous /do_objective requests by requiring exactly one of objective_name or objective_xml_string and publishing an actionable warning when the request is rejected.
  • Fixed UI notifications and pose markers being dropped when several Behaviors publish them within a few milliseconds of each other.
  • Fixed repeated missing-color warnings when point-cloud Behaviors process valid geometry-only clouds.
  • Fixed a crash in the MoveIt Pro Runtime when a joint state publisher reported joint names without positions while a URDF tool was attached. Joint states that do not pair one position with each name are now rejected, and a tool is no longer posed from a non-finite or multi-variable joint value.
  • Fixed the waypoint manager serving hand-edited waypoints whose joint names and values have different lengths. Waypoints with mismatched counts, or with a joint listed under the wrong joint-state array, are now dropped on load with an error naming the waypoint, the file, and the cause.
  • Fixed a Subtree port whose model declares no default failing the whole Objective at startup with is defining a mandatory port called [...], but you are not remapping it. Such a port is now remapped to an empty value, so the Objective builds.
  • Fixed a Subtree port whose model declares an empty default being impossible to leave unset. The port editor now offers Unset for it and saving keeps the attribute omitted, so the Runtime applies the declared default, and the unset badge distinguishes a declared empty default from no declared default at all instead of warning that the port would fail.
  • Fixed a missing mandatory Subtree port remap being silently replaced with an empty value. An Objective that omits a required remap now reports the missing remap when the tree is built, instead of running with an invented empty constant.
  • Fixed Script added from the Behavior palette silently succeeding without running its code, and Precondition failing with an unattributable error, because the Behavior catalog advertised an empty default for ports that have none. These ports are no longer pre-filled when the node is added, and a missing required value is reported against the port when the node runs.
  • Fixed the Teleoperate Objective overriding the Request Teleoperation Subtree's user_interaction_prompt default with an empty string. The declared prompt now applies, so enabling user interaction on that Objective shows the intended text instead of a blank prompt.
  • Fixed a Behavior Tree parameter named xmlns being saved into an Objective, which then failed to load with a server error on every attempt to open it. The name is now rejected when the Objective is saved, and an Objective that fails to load now reports its name, its file, and the reason the Runtime could not read it instead of only a server error.
  • Fixed PATCH /objectives/{id}/data, POST /objectives, and the MCP Objective authoring tool accepting raw Objective XML that binds an XML namespace, which produced an Objective that could neither be opened nor run, and in one spelling could no longer be found by ID at all. All three now reject it with a message naming the offending element or attribute and how to fix it.
  • Fixed Objectives being shown as editable when their files cannot be written, which made the Desktop App offer an edit the Runtime then rejected.
  • Fixed live Objective updates being lost or overwritten in the Desktop App editor, and creating, displaying, editing, and renaming Objectives whose names contain apostrophes.
  • Fixed MCP execution status losing an Objective's final outcome after it finished, and an MCP Runtime launch remaining blocked by a reservation from an exited launcher.
  • Fixed moveit_pro mcp serve leaving its container and session files behind when the AI client stopped it with SIGTERM or SIGHUP, and moveit_pro mcp serve --instance <name> taking shutdown ownership from a running moveit_pro run --instance <name>, which could stop that Runtime from shutting down its services.
  • Fixed JointTrajectoryAdmittanceController refusing to deactivate while a trajectory was executing, which let a robot stopped by its driver (for example on a protective stop) report the trajectory, and the Objective, as succeeded. The controller now aborts the executing goal with INVALID_STATE and deactivates; a SwitchController that deactivates it mid-trajectory succeeds and fails the executing Behavior instead of being refused.
  • Fixed JointTrajectoryAdmittanceController running a goal whose path or goal tolerance is zero, negative, or not a number, which it now rejects before the robot moves. In ExecuteTrajectory and ExecuteMTCSolution, set goal_position_tolerance to a positive value or remove it to use the controller's default_goal_tolerance.
  • Fixed JointTrajectoryAdmittanceController rejecting every new goal after the joints left the path tolerance on the last control cycle of a trajectory.
  • Fixed the Joint Trajectory Admittance Controller stopping over the full-speed distance when time_scale_percentage is below 100; stops now brake at stop_accelerations, so stopping distance shrinks with the square of the time scale, and the controller no longer holds its position command before braking after cancellations and controller faults.
  • Fixed unstable time scaling in the Joint Trajectory Admittance Controller with small time_scale_filter_constant values, and rejected non-positive or non-finite constants.
  • Fixed the Joint Trajectory Admittance Controller stopping an executing trajectory when it received a goal it could not stitch to; it now refuses the new goal and leaves the running one alone.
  • Fixed payload gravity compensation in the Joint Trajectory Admittance Controller so goals use their configured end-effector mass, center of gravity, and gravity_vector, including with rotated force/torque sensors. Use zero end-effector mass when sensor measurements already exclude payload weight.
  • Fixed the admittance controller accepting changes to configuration-only parameters without applying them. Runtime changes to sensor frames, sensor names, force/torque filter cutoff, stopping accelerations, and the time-scale filter constant are now rejected. Set these values in the initial controller configuration; changing them requires unloading and loading the controller with updated configuration.
  • Fixed collision checking being shared across teleoperation modes. Turning it off in Joint teleoperation no longer disables it for Pose teleoperation, and each mode keeps its own setting.
  • Fixed a race condition that could let the robot keep jogging with collision checking skipped after an operator turned it back on mid-motion.
  • Fixed coverage path generation rejecting flat regions with zero thickness.
  • Fixed the coverage path generated from a region drawn on a camera image being rotated away from the selection and extending past it.
  • Fixed the heading of a pose picked with GetPoseFromUser depending on the 3D view's Fixed Frame; it now follows the robot's URDF root link.
  • Fixed the AdjustPoseWithIMarker marker jumping after a drag, and Localize Robot rejecting its pose, when the 3D view's Fixed Frame is not the robot's model frame.
  • Fixed captured point cloud snapshots not appearing in the orthographic axis views of the 3D Visualizer.
  • Fixed incorrect or black colors when streaming point clouds from cameras that store packed colors in floating-point fields to the Desktop App.
  • Fixed the occupancy grid hiding the ground grid and the scene beneath it. Free space is now transparent, unknown cells are shown in gray rather than red, and the map no longer flickers against the ground grid as the camera moves.
  • Fixed measurement labels being cut in half by the surface they measure, and being scaled and offset incorrectly after a view pane is made fullscreen.
  • Fixed keep-out zone sizes and positions reverting to the slider limits when a larger value was typed. Size and position are now set with a jog strip that has no end of travel: drag it to raise or lower the value by any amount, hold Shift for finer control, or type the number directly. Size accepts anything above 0.01 m and position is unrestricted.
  • Fixed the move-and-rotate gizmo around a keep-out zone keeping its original size after the zone was resized, which left the rings far too large for a zone that had been made smaller.
  • Fixed a keep-out zone created or cloned while keep-out zones were locked having no interactive marker, so it could not be moved, rotated, or re-selected in the 3D Visualizer. Creating a zone now unlocks the planning scene.
  • Fixed toggles being hard to read. An off toggle is now neutral gray and an on toggle green, instead of two shades of blue that differed only in brightness; in the training panel an off toggle previously had no visible track at all. Toggles also draw a focus ring when reached with the keyboard.
  • Fixed the Alert Sidebar recording one row per open panel each time the robot's joint states dropped out and came back, instead of one row per event.
  • Fixed duplicate Objective requests splitting one execution's alerts across multiple Alert History sections.
  • Fixed Trainer episode lists remaining stale after deleting an episode and recording another.
  • Fixed recording started outside the Desktop App being allowed during playback, including preparation and shutdown, and Trainer's Record tab naming the selected dataset, rather than the one being recorded, when the selection changed during a recording.
  • Fixed the train-model skill reusing stale Weights & Biases credentials on shared RunPod volumes and leaving credentials behind when private file permissions could not be enforced.
  • Fixed unwanted automatic inference server restarts. Restart a failed server with moveit_pro run --only-inference-server.
  • Fixed ML inference logs reporting a CPU fallback when CPU was requested, and ML runtime messages missing from MoveIt Pro logs.
  • Fixed the license fingerprint under WSL2 (Windows Subsystem for Linux) changing on every WSL restart. The fix requires mirrored networking, listed under Breaking Changes. Core
  • Fixed startup errors for rejected robot descriptions to show the specific validation failure instead of a generic crash or misleading license guidance. Core
  • Fixed moveit_pro export_logs ignoring MOVEIT_HOST_LOG_DIR and including the targets of symbolic links. Skipped log entries are reported during export.
  • Fixed missing startup errors when a Runtime container fails before log streaming begins; moveit_pro run now recovers and saves the failed container's output in both normal and verbose modes.
  • Fixed global --verbose being ignored by moveit_pro run and moveit_pro update_acm.
  • Fixed moveit_pro configure reporting success after the user canceled it.

Breaking Changes​

  • Custom Behavior plugins must be rebuilt for this release. The Behavior Tree library's version changed, so a prebuilt plugin shipped inside a derived container image fails to load until you rebuild it with moveit_pro build. A workspace you build from source needs only the one-time clean rebuild below.
  • A user workspace built on an earlier release must be rebuilt once from clean after upgrading, because MoveIt Pro library file names changed. Run moveit_pro build user_workspace --colcon-args "--cmake-clean-cache", or delete the workspace's build/, install/, and log/ directories before moveit_pro build. Library file names no longer change on every patch release, so later patch releases will not need this. Core
  • A custom Behavior registered with the ID Finally conflicts with the new built-in Finally control node and must be renamed.
  • Activating a node-locked license under WSL2 (Windows Subsystem for Linux) now requires networkingMode=mirrored in .wslconfig and Windows 11 22H2 or later. An install left in the default network address translation mode fails activation with steps to switch, and a WSL machine activated before this release reactivates once after switching. Core
  • The dev service that moveit_pro dev starts now requires a rootful Docker daemon, as drivers already did, because it carries the rtprio and memlock limits that realtime scheduling needs and a rootless daemon cannot raise them.
  • The moveit-pro-license helper no longer runs on Debian Bookworm now that it ships as a native binary instead of a bundled Python environment. Core
  • The Objective editor and the REST API now refuse to save an Objective or Subtree named Root or root, or whose name contains <, >, &, ", /, \, :, *, ?, |, or a control character. The REST API did not check these names before. An Objective already saved under such a name still loads and runs, so you can open it and rename it in the editor. The editor now also accepts periods, parentheses, and non-ASCII characters, which it previously rejected, so names like Test Presoak 1.2 and Move to Waypoint (JTC) can be typed.
  • A Subtree or Objective port declaration must now start with a letter. Rename a port such as _my_port to my_port. BehaviorTree.CPP never bound a port with a leading underscore at a Subtree call site. Node attributes such as _while and _skipIf are unaffected. The Objective editor rejects the name where it is typed, and saving an Objective that still declares one returns an error naming the port. An Objective that already declares such a port still opens, so you can fix it in the editor.
  • The MoveIt Pro Simulator now refuses to start a configuration that would give a transform frame two parents, where it previously ran with broken TF, and names the fix in the error: a planar joint between the URDF root and the base link (make it fixed, or floating with a same-named MuJoCo free joint); a floating joint other than the base's own parent joint, unless it is off the root-to-base path and listed in ignore_joint_validation; a base parent floating joint below the URDF root or under an odom_frame other than the root (root the URDF at that joint's parent link and leave odom_frame unset, or set base_pose_source: robot_state_publisher); a base moving with a MuJoCo free joint under a non-floating URDF parent joint (make that joint floating, or set odom_frame to an odometry frame outside the URDF); odom_frame set to mj_world or a URDF link below the root; and a URDF link, MuJoCo body, or site named <base link>_ground_truth, which the Simulator now publishes itself.
  • JointTrajectoryAdmittanceController now aborts a trajectory with GOAL_TOLERANCE_VIOLATED when the joints end outside the goal tolerance, where it reported success before. ExecuteTrajectory, ExecuteMTCSolution, and ExecutePolicy now fail where they passed with the joints off target. For a motion that ends in contact, set goal_position_tolerance to cover the expected deviation. For a simulation or robot that lags the commanded trajectory, raise default_goal_tolerance in the controller configuration or set the new default_goal_time_tolerance parameter, which gives the joints that many seconds after the trajectory end time to come within the goal tolerance before the goal aborts.
  • Removed apt-owned pytest implementation and metadata paths from Runtime images containing the pytest 9.0.3 security update; use the supported /usr/local/lib/ installation through python3 -m pytest and remove hard-coded apt pytest paths and pytest-specific import-path overrides. See the migration guidance.
  • moveit_pro_ml::DeviceKind and moveit_pro_ml::DevicePreference gain an Npu value. Code with an exhaustive switch over either enum needs a case for it.
  • Removed TransformsConstPtr, TransformsWeakPtr, TransformsConstWeakPtr, TransformsUniquePtr, TransformsConstUniquePtr, Transforms::transformVector3, and Transforms::transformRotationMatrix from MoveIt Pro Core. Replace the pointer aliases with the equivalent std smart-pointer specializations, and replace either helper call with output = transforms.getTransform(from_frame).linear() * input. Core
  • ASSIGN_OR_RETURN and ASSIGN_OR_RETURN_WITH_PREFIX now move the value into the left-hand side. Code that declared the left-hand side as a non-const reference, such as ASSIGN_OR_RETURN(T& value, ...), no longer compiles; declare it by value or as const T&. Core
  • Removed the unused moveit_pro_base_py::moveit_py_utils target, moveit_py/moveit_py_utils/copy_ros_msg.h, moveit_py/moveit_py_utils/copy_ros_msg.hpp, and their 16 moveit_py::moveit_py_utils conversion functions. Downstream bindings should depend on picknik_py_binding_tools, link picknik_py_binding_tools::picknik_py_binding_tools, include <picknik_py_binding_tools/ros_msg_typecasters.h>, and expose typed ROS message parameters and return values through the provided pybind typecasters. Core
  • Removed moveit_pro_base/version.hpp, its compile-time version and git-identity macros, and the moveit_pro_version executable. Replace moveit_pro_version with moveit_pro --version; the removed compile-time macros and git-identity output have no direct replacement. Core
  • Removed unused RobotTrajectory APIs: size() (use getWayPointCount()); getWayPointDurationFromStart(), findWayPointIndicesForDurationAfterStart(), and getStateAtDurationFromStart() (accumulate getWayPointDurations() or getWayPointDurationFromPrevious() and interpolate between getWayPoint() results, or use getDuration() when only the final duration is needed); the addPrefixWayPoint(), insertWayPoint(), and removeWayPoint() overloads (rebuild the waypoint sequence with addSuffixWayPoint()); print() and its stream operator (format trajectory data from getWayPointCount(), getWayPoint(), and the duration accessors); the pathLength(), smoothness(), and waypointDensity() helpers (compute application-specific metrics from the waypoints); and toJointTrajectory() (call getRobotTrajectoryMsg() and consume its joint_trajectory member, handling multi-DOF joints explicitly when needed). Core
  • Removed unused color-manipulation, plane, and cone helpers from the legacy moveit_pro_rviz_marker_tools C++ API. Rebuild dependents, continue using the retained color identifiers with setColor, and construct the corresponding planar or cone visualization_msgs::msg::Marker values directly. Core
  • Selected MTC stage, container, and task constructors are now explicit. Use ContainerType(impl) for a concrete container or direct base initialization from its implementation pointer, and replace copy-list initialization with direct-list initialization such as Task task{}; std::make_unique<T>(...) construction is unaffected. Construct InterfaceState(scene), SubTrajectory(trajectory), and SolutionSequence(std::move(parts)) explicitly; InterfaceState copy construction is unaffected. Construct InterfaceFlags(enum_value) and Interface::UpdateFlags(enum_value) explicitly from enums, while implicit integer flag use remains supported. Wrap list iterators with Interface::iterator(...) or Interface::const_iterator(...) when passing or assigning them to those adapters, including mutable-to-const conversion. Use static_cast<bool>(planner_result) or planner_result.success when assigning or returning planner results as ordinary booleans, while contextual conditions such as if (planner_result) remain supported. Replace cost_ordered::push(std::pair<...>) with insert(value, cost), or construct the queue's value_type before passing it to push. Directly construct the MTC Interface callback type, the Interface::DisableNotify scoped guard, MarkerVisualizationProperty, and TaskSolutionPanel when converting callbacks, interface references, names, or parent pointers. Core