Changelog¤
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[2.0.1] 2026-06-18¤
Added¤
Changed¤
Removed¤
[2.0.0] 2026-06-18¤
Added¤
- New
MoveItCheckCollisionbackend feature:MoveItPlannernow implements theCheckCollisioninterface (the sameplanner.check_collision(state)asPyBulletPlanner), backed by MoveIt's/check_state_validityservice (moveit_msgs/GetStateValidity). It does a stateless collision + constraint check of the state against the planning scene currently loaded intomove_group— no planning, no IK — and raisesCollisionCheckErrorlisting the colliding body pairs. AddsGetStateValidityRequest/GetStateValidityResponseROS message wrappers. - The
Inverse Kinematics,Plan MotionandPlan Cartesian MotionGrasshopper components now explain a failure with a concise collision check on the start state, via a sharedcollision_diagnostichelper incompas_fab.ghpython: when the planner supports collision checking and the start state is in collision, the colliding pairs (e.g.forearm_link<->shoulder_link, +2 more) are appended; otherwise it notes the state is collision-free (likely a reachability issue). Planners without collision checking are handled gracefully. Each of these components also gained adebug_infooutput that mirrors the warning/error messages as a single string, so they can be read in a wired panel rather than only the component balloon. - New
Deconstruct Robot CellGrasshopper component that splits aRobotCellinto itsrobot_model, registeredrigid_bodiesandtools, and a matchingdefault_cell_state, the inverse of registering models via theLoad Robot Cellcomponents. - New
Deconstruct PlannerGrasshopper component that outputs therobot_cellandrobot_modelcurrently held by any planner (MoveIt, PyBullet, analytical). The cell state is intentionally not exposed — the planner's last-set state is rarely the one you want; build it explicitly viaDefault Cell State/ theAttach*components instead. - New
MoveIt Planner OptionsGrasshopper component (andMoveItPlannerOptionsclass incompas_fab.ghpython) that bundles the advanced load parameters (urdf_param_name,srdf_param_name,http_file_server_base_url) into a single object for theMoveIt Planner's optionaloptionsinput. It is a plain class rather than a dict/namedtuple so it crosses a Grasshopper wire as one object instead of being exploded into its keys. Load Robot Cell From LibraryandMoveIt Plannerauto-create a Boolean Toggle on theirload_geometryinput, andROS Clientauto-creates one (defaulting to off) on itsconnectinput — via the newensure_boolean_togglehelper incompas_fab.ghpython, so these can be flipped on/off with one click instead of wiring a separate toggle.- New
RobotCell.structural_signature()method: a stable fingerprint (robot model name + sorted tool and rigid-body ids) of a cell's structural identity. Consolidates a helper that was previously duplicated as a private function inActionChain, and is reused by theMoveIt Plannercomponent to decide when the planning scene needs re-uploading. FrameInterpolatorandPointAxisInterpolatorare now public (compas_fab.robots). They were private helpers buried in the PyBullet Cartesian-motion backend feature, but are backend-agnostic (only depend oncompas.geometry) and useful on their own for interpolating between poses / point-axis pairs with bounded Cartesian and angular steps. Their constructors now take explicit keyword arguments (max_step_distance,max_step_angle,min_step_distance,min_step_angle) instead of an opaqueoptionsdict.- New API documentation pages for the analytical-kinematics backend (
compas_fab.backends.kinematicsandcompas_fab.backends.kinematics.backend_features), which had no API page while the ROS and PyBullet backends did — soAnalyticalKinematics,AnalyticalKinematicsClient,AnalyticalForwardKinematics,AnalyticalPybulletInverseKinematics,AnalyticalSetRobotCellandAnalyticalSetRobotCellStatewere undocumented.AnalyticalKinematics(the solver base class) is now also re-exported fromcompas_fab.backends.kinematics. compas_fab.rhinonow re-exports its scene objects (RigidBodyObject,RobotCellObject,RobotModelObject) likecompas_fab.ghpythonalready did, so they appear in the API docs instead of being hidden in a submodule.-
MoveItResetPlanningSceneis now exported fromcompas_fab.backends.ros.backend_features(it was the only one of the eight MoveIt backend-feature classes missing from the package__init__/__all__, so it never showed up in the docs). -
New backend page Analytical IK + PyBullet for
AnalyticalPyBulletPlanner, the hybrid planner that pairs closed-form analytical IK with PyBullet collision checking. Previously this backend was undocumented despite being shipped incompas_fab.backends. docs/backends/pybullet.mdnow flags that free-spaceplan_motionis not yet implemented forPyBulletPlanner(Cartesian motion viaplan_cartesian_motionworks).- New
ros2-ur10e-demodocker reference backend (ROS 2 Jazzy + MoveIt 2 + UR10e) with aur-simservice running the officialuniversalrobots/ursim_e-seriesPolyscope simulator, azenoh-routerservice runningrmw_zenohdas the RMW transport (replaces DDS, no more multicast discovery issues on Docker Desktop), aur-driverservice running the realur_robot_driveragainst the simulator (with the ros2_control + RTDE update rate lowered from the default 500 Hz to 100 Hz via a baked-inupdate_rate.yaml, to stop the controller manager from spamming "Overrun detected!" warnings under Docker virtualisation),moveit-demorunningur_moveit.launch.py, rosbridge on9090, an HTTP file server on9091for serving meshes from/opt/ros/jazzy/share/, and atheasp/novncweb GUI on8080for viewing RViz. - New
compas_fab.backends.HttpFileServerLoaderthat mirrorsRosFileServerLoader's interface but fetches meshes over plain HTTP and reads URDF/SRDF from rosbridge topics (the ROS 2 convention) instead of ROS parameters. - Migrated documentation from Sphinx to MkDocs Material, matching the structure used in
compas_robots. Newmkdocs.ymlat the repository root; documentation sources are now Markdown (docs/*.md) with API pages driven bymkdocstrings. Backlinks are disabled.inventoriesincludescompas,compas_robots, andcompas_viewer. Sphinx config (docs/conf.py) and Sphinx-onlydocs/requirements.txthave been removed;tasks.pynow invokescompas_invocations2.mkdocs.docssoinvoke docsbuilds the MkDocs site. - New developer guide section: Backend architecture ported from the old
docs/developer/backends.rst, plus Grasshopper components ported fromdocs/developer/grasshopper.rst. - New Icon system page documenting the Grasshopper component icon design system (24×24 artboard, 1.8 px monoline keyline, shared primitive kit — cube=cell, square=body, cone=tool, triad=frame, ring=goal, polyline=motion, brackets=library, chip=backend, teal accent for the semantic subject). Ships the editable SVG source (
icons.js) and a standalone catalog/spec sheet (icon_system.html) showing all glyphs grouped by subcategory with a Grasshopper-style preview. - Re-rendered every
Cf_*componenticon.pngfrom the new design system — consistent stroke weight, shared primitive kit, teal accent for the semantic subject of each icon. Affects everysrc/compas_fab/ghpython/components_cpython/*/icon.png. - New API pages explicitly exposing
compas_fab.backends.interfaces,compas_fab.backends.ros.backend_featuresandcompas_fab.backends.pybullet.backend_featuresviamkdocstrings, replacing the Sphinxautosummarytables that previously generated stub.rstfiles per symbol. - New
TargetandWaypointsclasses to represent inputs of planning functions. - New
PointAxisTargetandPointAxisWaypointclasses for processes that have a cylindrical tool (e.g. drilling, milling, 3D printing). - New
TargetModeenum to specify how planning functions interpret a target frame. - New
TargetMode.Toolmode allow users to specify the target location of the attached tool. - New
TargetMode.WORKPIECEmode allow the same for the attached workpiece. - Forward kinematics functions also support target mode to return Robot, attached Tool or attached Workpiece frame.
- New
RobotCellclass to represent all objects in a a robot cells, namely the RobotModel, ToolModel(s) and RigidBody(s). RobotSemantics is also here. ReplacedRobotclass. - New
PlannerInterface.set_robot_cellfunction for the user to pass the robot cell to the planner. - New
RigidBodyclass support separated Visual and Collision geometries. - New
RobotCellStateclass to represent state of all objects in the robot cell, including robot Configuration, robot base frame (new), ToolState(s) and RigidBodyState(s). - New
RobotCellState._robot_base_frame(relative to WCF) can now be changed by user.- Note that all RigidBody frames and Target frames are still relative to WCF (conceptually the same as before).
- New
ToolStateclass includes tool configuration (for kinematic tools) and attachment state (group and attachment frame) of the tool to the robot. - New
ToolState.attachment_frameallows users to change the attachment location of a tool relative to the end-effector link. - New
RigidBodyStateclass can model both options of attaching the object to a robot link (e.g. cable dress-pack) and attaching to the tool (which is now referred to as a Workpiece). - Planning backends are redesigned to have stateless planning functions (e.g.
collision_check,inverse_kinematics,plan_motion). - Stateless planning functions requires
RobotCellStateinput, allowing different object states between planning calls. - It avoids the need for the user to keep track of the state in the planner between planning calls and even sessions.
- It allows cleaner implementation when batch planning multiple motions with different attachment relationships.
- New functions for
PyBulletPlanner. - New
PlanCartesianMotionfunction forPyBulletPlanner. Compatible withFrameWaypointsandPointAxisWaypoints. - New
InverseKinematicssupport for random restarts. - New
CollisionCheckfunction forPyBulletPlanner. - New support for
ToolModelswith kinematic joints. - Supported by both
PyBulletPlannerandMoveItPlanner. - Allows users to model tools with moving parts (e.g. grippers jaws) for more accurate collision checking.
- New
RobotCellLibrary,ToolLibraryandRigidBodyLibraryclasses to quickly load pre-defined objects for tests, examples and demos. - New
RobotCellLibrarycontains pre-defined robots (e.g. UR5, UR10e, Panda, ABB IRB120, ABB IRB4600 and RFL) and also cells with tools and rigid bodies. - New
ToolLibrarycontain examples of static and kinematic tools. - New script to extract robot packages (URDF, SRDF and meshes) from the ROS docker to create new
RobotCellLibraryobjects. - New
SceneObjectclasses for visualization - Users should use the
RobotCellObjectclass, which can visualize the entire robot cell. - Users should first call
.update()with the state class, then call.draw()to draw native CAD geometries. - A temporary
RobotModelObjectclass is provided to avoid changing the existing one incompas_robots - Redesigned the mechanism for dealing with non-meter scale input and output.
- Input: User created
RigidBodycan contain meshes that are not in meters by setting the.native_scaleattribute.RigidBody.visual_meshes_in_meters()andRigidBody.collision_meshes_in_meters()functions can return the meshes in meters.
- Input: User created
ToolModelmust be in meters to align withcompas_robot.RobotModelthat is always in meters. - Input: User created
TargetsandWaypointscan have a.native_scaleattribute to specify the scale.- Both classes have
.normalize_to_meters()and.normalized_to_meters()functions to convert the target to meters.
- Both classes have
- Output: Forward kinematics functions can return frames at other scales by setting the optional
native_scaleparameter. - Output:
SceneObjectclasses for visualization have anative_scaleattribute to specify the drawing scale. - Input / Output:
ConfigurationandTrajectoryobjects always uses the Meter-Radian units, in accordance with ROS convention.- Conversion of joint values to other units for execution should be done by the user based on robot controller requirements.
- All the
native_scaleattribute has the same meaning whereuser_object_value * native_scale = meter_object_value.- In typical use, all
native_scaleattribute can be set to the same value, regardless of input or output. - For example, if the user wants to work with millimeters, set all
native_scaleto'0.001'.
- In typical use, all
- Added
compas_fab.robots.RobotCellclass. - Added
compas_fab.robots.RobotCellLibraryclass. - Added
compas_fab.backends.BackendTargetNotSupportedError. - Added
compas_fab.backends.TargetModeMismatchError. - Added
compas_fab.backends.PlanningGroupNotExistsError. - Added
compas_fab.backends.CollisionCheckError. - Added
compas_fab.backends.MotionPlanningError. - Added
compas_fab.backends.MPStartStateInCollisionError. - Added
compas_fab.backends.MPTargetInCollisionError. - Added
compas_fab.backends.MPInterpolationInCollisionError. - Added
compas_fab.backends.MPSearchTimeOutError. - Added
compas_fab.backends.MPNoIKSolutionError. - Added
compas_fab.backends.MPNoPlanFoundError. - Added
compas_fab.backends.MPMaxJumpError. - Added
compas_fab.backends.AnalyticalKinematicsClient. - Added
compas_fab.backends.AnalyticalKinematicsPlanner. - Added
compas_fab.backends.AnalyticalPyBulletPlanner. - Added
compas_fab.backends.CollisionCheckError. - Added
compas_fab.backends.PlanningGroupNotSupported. - Added
messageandtarget_pcfattributes toInverseKinematicsError. - Added
compas_fab.backends.CheckCollisionto backend features. - Added
compas_fab.backends.SetRobotCellto backend features. - Added
compas_fab.backends.SetRobotCellStateto backend features. - Added
compas_fab.backends.ClientInterface.robot_cellas read-only property. - Added
compas_fab.backends.ClientInterface.robot_cell_stateas read-only property. - Added
compas_fab.backends.ClientInterface.robot_modelas read-only property. - Added
compas_fab.backends.ClientInterface.robot_semanticsas read-only property. - Added
compas_fab.backends.PlannerInterface.set_robot_cell()as a possible mix-in method. - Added
compas_fab.backends.PlannerInterface.set_robot_cell_state()as a possible mix-in method. - Added
compas_fab.backends.PlannerInterface.check_collisions()as a possible mix-in method. - Added
compas_fab.backends.PlannerInterface.iter_inverse_kinematics()as a possible mix-in method. - Added
compas_fab.backends.kinematics.backend_features.AnalyticalPlanCartesianMotionforAnalyticalKinematicsPlanner. - Added
compas_fab.backends.kinematics.backend_features.AnalyticalForwardKinematicsforAnalyticalKinematicsPlanner. - Added
compas_fab.backends.kinematics.backend_features.AnalyticalInverseKinematicsforAnalyticalKinematicsPlanner. - Added
compas_fab.backends.kinematics.backend_features.AnalyticalSetRobotCellforAnalyticalKinematicsPlanner. - Added
compas_fab.backends.kinematics.backend_features.AnalyticalSetRobotCellStateforAnalyticalKinematicsPlanner. - Added
compas_fab.backends.kinematics.backend_features.AnalyticalPybulletInverseKinematicsforAnalyticalPyBulletPlanner. - Added
compas_fab.backends.pybullet.backend_features.PyBulletCheckCollisionforPyBulletPlanner. - Added
compas_fab.backends.pybullet.backend_features.PyBulletPlanCartesianMotionforPyBulletPlanner. - Added
compas_fab.backends.pybullet.backend_features.PyBulletSetRobotCellforPyBulletPlanner. - Added
compas_fab.backends.pybullet.backend_features.PyBulletSetRobotCellStateforPyBulletPlanner. - Added
compas_fab.backends.pybullet.backend_features.MoveItSetRobotCellforMoveItPlanner. - Added
compas_fab.backends.pybullet.backend_features.MoveItSetRobotCellStateforMoveItPlanner. - Added
compas_fab.backends.ForwardKinematics.forward_kinematics_to_link(). - Added
compas_fab.robots.ToolLibraryclass. - Added
compas_fab.robots.ToolLibrary.cone(). - Added
compas_fab.robots.ToolLibrary.printing_tool(). - Added
compas_fab.robots.ToolLibrary.static_gripper(). - Added
compas_fab.robots.ToolLibrary.static_gripper_small(). - Added
compas_fab.robots.ToolLibrary.kinematic_gripper(). (example of a kinematic tool) - Added
compas_fab.robots.RigidBodyLibraryclass. - Added
compas_fab.robots.RigidBodyLibrary.target_marker(). - Added
compas_fab.robots.RobotCellLibraryclass. - Added
compas_fab.robots.RobotCellLibrary.rfl(). - Added
compas_fab.robots.RobotCellLibrary.ur5(). - Added
compas_fab.robots.RobotCellLibrary.ur10e(). - Added
compas_fab.robots.RobotCellLibrary.abb_irb4600_40_255(). - Added
compas_fab.robots.RobotCellLibrary.abb_irb120_3_58(). - Added
compas_fab.robots.RobotCellLibrary.panda(). - Added
compas_fab.robots.RobotCellLibrary.ur5_cone_tool(). - Added
compas_fab.robots.RobotCellLibrary.abb_irb4600_40_255_gripper_one_beam(). - Added
compas_fab.robots.RobotCellLibrary.ur10e_gripper_one_beam(). - Added
compas_fab.robots.RobotCellLibrary.abb_irb4600_40_255_printing_tool(). - Added
compas_fab.robots.RigidBodyclass. - Added
compas_fab.robots.RigidBodyStateclass. - Added
compas_fab.robots.RobotCellclass. - Added
compas_fab.robots.RobotCellStateclass. - Added
compas_fab.robots.ToolStateclass. - Added
compas_fab.robots.RobotCell.from_urdf_and_srdf(). Absolute paths passed forlocal_package_mesh_folderare now used as-is; relative paths still resolve againstcompas_fab.DATA(the existing shorthand for the bundled robot library, e.g."robot_library/ur5_robot", keeps working). Previously, routing absolute paths throughcompas_fab.get()stripped their leading slash and produced a malformed<DATA>/<absolute-path>join that never resolved. - Added
compas_fab.robots.Targetclass. - Added
compas_fab.robots.ConfigurationTargetclass. - Added
compas_fab.robots.ConstraintSetTargetclass. - Added
compas_fab.robots.FrameTargetclass. - Added
compas_fab.robots.PointAxisTargetclass. - Added
compas_fab.robots.TargetModeclass. - Added
compas_fab.robots.Waypointsclass. - Added
compas_fab.robots.FrameWaypointsclass. - Added
compas_fab.robots.PointAxisWaypointsclass. - Added
compas_fab.robots.FrameWaypointsclass. - Added docker file for UR5-demo with GUI turned on by default.
- Added various example files (detailed list to be added later).
- Added
pragma: no coverto all type-checking imports for better coverage report accuracy. - Added support for python '3.11'.
- Added tests for
PyBulletClientandPyBulletPlannerbackend features, including Ik and FK agreement tests. - Redesigned the Grasshopper component library (CPython / Rhino 8) for the new stateless planning model. The legacy IronPython
components/set was retired; all components now live undersrc/compas_fab/ghpython/components_cpython/and target Rhino 8 CPython exclusively. New categories under "COMPAS FAB": - Backends —
Cf_RosClient(with atransportinput —twisted/asyncio/cli— forwarded toroslibpy.RosviaRosClient's new**kwargspass-through; falls back to roslibpy's process-wide default when empty; the input requires roslibpy >= 2.1 and is ignored with a warning on older versions),Cf_MoveItPlanner,Cf_AnalyticalKinematicsPlanner,Cf_PyBulletPlanner(in-process collision checking, FK/IK and Cartesian motion) andCf_AnalyticalPyBulletPlanner(closed-form analytical IK paired with PyBullet collision checking, via a solver dropdown). Both PyBullet planner components manage their own in-process PyBullet client — pass aRobotCelland optionally pick the connection type (direct/guivia an auto-created dropdown); the component connects, builds the planner, appliesset_robot_cell, and caches the client across canvas refreshes, so there is no separate client component to wire. - Robot Cell —
Cf_LoadRobotCellFromLibrary(with an auto-created dropdown listing everyRobotCellLibraryentry),Cf_LoadRobotCellFromUrdfSrdf,Cf_RigidBodyFromMesh,Cf_ToolFromLibrary,Cf_RigidBodyFromLibrary. The twoLoadRobotCell*components each taketoolsandrigid_bodieslist inputs and register them into the cell as part of loading (keyed by each item's.name), so a complete cell reaches the planner in one shot — there is no separateAdd* → set_robot_cell()step to forget. (Loading from ROS works the same way but is folded into theMoveIt Plannercomponent, since MoveIt's cell can only come frommove_group.)RigidBodygained anamefield (surfaced as thename/rigid_body_idinputs on the rigid-body builders) so a body is self-describing like aToolModel. - Cell State —
Cf_DefaultCellState,Cf_SetRobotConfiguration,Cf_AttachToolToRobot(auto-creates a dropdown of every tool in the wired cell whentool_idis unwired, refreshed when the cell's tool set changes; emits a remark naming the actual link the tool ends up attached to, e.g.tool0for UR groups —attachment_planecorrects any per-robot EE-axis convention quirks) andCf_AttachRigidBodyToLink(both auto-defaulttouch_linksfrom the cell when unwired —AttachToolToRobotpicks the group's end-effector link plus its parent when the EE link is geometry-less, e.g. URtool0→flange;AttachRigidBodyToLinkpicks the link the body is attached to. A warning surfaces the auto-pick so it isn't silent),Cf_AttachRigidBodyToTool,Cf_SetRigidBodyFrame,Cf_SetTouchLinks. - Targets —
Cf_FrameTarget,Cf_PointAxisTarget,Cf_ConfigurationTarget,Cf_FrameWaypoints,Cf_PointAxisWaypoints(tightenedpointsinput tolist[Rhino.Geometry.Point3d]so the script harness marshals each item as a realPoint3drather than the per-coord float flattening produced by the genericList[object]typing),Cf_RobotConfiguration(auto-creates oneGH_NumberSliderper configurable joint with the joint's limits, all wired to a singlejointslist input — drop and wire arobot_celland the slider bank appears; values flow through the standard GH solve path). - Planning —
Cf_ForwardKinematics,Cf_InverseKinematics(accepts a barecompas.geometry.Frameor RhinoPlaneastargetand auto-wraps it asFrameTarget(target_mode=ROBOT); defaultsstart_stateto a zero-config state derived fromplanner.robot_cellwhen unwired; warns whenplannerortargetare wired but received None; emits both theconfigurationand an updatedcell_statesoVisualize/ForwardKinematics/ the next planner step can wire straight in without aCf_SetRobotConfigurationstep in between),Cf_PlanMotionandCf_PlanCartesianMotion(withplanesandpolylineoutputs — Rhino planes at the planning group's EE per trajectory point and a polyline through their origins — viaJointTrajectory.to_frames_and_polyline, computed locally throughRobotCell.forward_kinematics_target_frameso no round trip per point. Planning failures flag the component red with the backend error message; no separateerroroutput),Cf_DeconstructTrajectory(expands aJointTrajectoryinto a list ofConfigurations, parallelRobotCellStatesderived fromtrajectory.start_state, and DataTrees ofvelocities/accelerations/efforts— one branch per point — for plotting the trajectory profile; pipe an index slider into thecell_statesoutput to scrub throughVisualizeRobotCell). - Display —
Cf_VisualizeRobotCell(uses theRobotCellObjectscene object with native-geometry caching for smooth slider scrubbing). - ROS —
Cf_RosTopicPublish,Cf_RosTopicSubscribe(ported to the newRosClient). - Planner calls take a
RobotCell+RobotCellState+Target/Waypointstriple. Long-lived clients/planners usescriptcontext.sticky; user messages flow throughcompas_ghpython.error/warning/remark. Loader errors are caught and surfaced via clean error messages rather than letting tracebacks reach the GH canvas. - Added
Cf_TrajectoryAction,Cf_StateChangeAction, andCf_ActionChainGrasshopper components under Planning. The two action builders wrap aJointTrajectory(or aRobotCellStatefor a discrete state change) into a namedActionnext to the data that produced it — names cannot drift out of sync with the underlying object — and accept an optional comma-separatedtagsinput that lands on the action'sattributes.Cf_ActionChaintakes the orderedactionslist, an optionalrobot_cell(for signature verification on load), and emits the assembledchainplus composite visualisation outputs: a DataTree of EE planes with one branch per trajectory action, a parallel list of polylines (one per action),durationandend_state. The viz reusestrajectory.to_frames_and_polylineper action, walking the chain's state sequence so each segment's FK uses the correct pre-state. The helper's signature was relaxed to takerobot_celldirectly (instead of digging throughplanner.client.robot_cell), making it reusable from any caller that already has a cell. - Added
compas_fab.robots.Actionandcompas_fab.robots.ActionChain— a higher-level assembly layer that threads a singleRobotCellStatethrough a sequence ofActionobjects. A singleActionclass covers both kinds: one carrying aJointTrajectoryis a planned action and derives its post-state from the predecessor (last-point applied); one without a trajectory is an unplanned (state-change) action (gripper toggle, tool attach/detach) and carries an explicit post-state. Using one class means backtracking/undo just clears the trajectory instead of swapping class types. Each action also carriestags(over a free-formattributesbag) to drive differentiated downstream execution (e.g.approach/retract, linear vs. free motion). The canonical use case is pick-and-place:ActionChain(name, start_state).append_trajectory(...).append_state_change(...)..., fluent chaining. Lookup is by name (chain.action_by_name(...)) rather than index, so a future tree/branching extension won't force an API break. Optionalrobot_cellconstructor argument stores a structural signature (robot name + tool/body ids, SHA-256) sochain.verify_cell(cell)fails loudly when a chain is loaded against the wrong cell. The chain owns the state sequence: eachAction.start_stateis mirrored onto the contained trajectory'sstart_state, and serialisation strips both (re-threaded on load) and omits the derivedpost_stateof planned actions; only the chain'sstart_stateand explicit state-change post-states are stored. Planners' return types are unchanged —ActionChainis purely an additive composition layer. - Added
compas_fab.robots.JointTrajectory.start_state— an optionalRobotCellStatethat carries the full cell context the trajectory was planned from (tools, rigid bodies, attached collision objects, robot configuration). MoveIt, PyBullet and analytical Cartesian planners now populate it. Breaking change: theJointTrajectoryconstructor signature is now(trajectory_points, joint_names, start_state, fraction, attributes)—start_configurationhas been removed from the constructor and is set via the property only (traj.start_configuration = configafter construction). The getter returns the explicit override if set, otherwisestart_state.robot_configuration.Cf_DeconstructTrajectoryderives its per-point cell states straight fromtrajectory.start_state(thestart_stateinput was dropped — the trajectory carries it), and thetrajectory_to_planes_and_polylineviz helper falls back totrajectory.start_statewhen its explicitstart_stateis unwired, so a planned trajectory now visualises end-to-end without re-wiring the cell state on the output side. - Added
compas_fab.ghpython.ensure_value_list, a reusable helper for components that want to auto-create a GrasshopperValue Liston an unconnected input (used byCf_LoadRobotCellFromLibraryand intended for follow-on components likeCf_FrameTarget'starget_modeand solver-name pickers). - Added
JointTrajectory.to_frames_and_polylineto ease visualization of trajectories.
Changed¤
JointTrajectory.to_frames_and_polylinegained an optionaltarget_modeparameter (defaults toTargetMode.ROBOT), so the visualized path can be reported at the robot's planner frame, the attached tool's TCF, or the workpiece. ThePlan MotionandPlan Cartesian MotionGrasshopper components now pass thetarget_modeof theirtarget/waypointsthrough to it, so the previewedplanes/polylinematch what was actually planned (e.g. the tool tip path for aTOOL-mode target).- The
MoveIt PlannerGrasshopper component now loads the robot cell from ROS itself, and the separateLoad Robot Cell From ROScomponent has been removed. MoveIt's planning scene is defined by the URDF/SRDF loaded intomove_group, so the cell can only come from ROS — merging the two removes a fragile two-step wiring (and the previousros_clientpass-through workaround that enforced load-before-plan ordering).MoveIt Plannernow takesros_client,tools/rigid_bodies(registered into the cell and uploaded as collision objects),load_geometry,reload, and an optionaloptionsinput, and outputsplanner(first),robot_cell, anddetected_distro. The cell is fetched once and cached (setreloadto refetch), and re-uploaded to the planning scene only when it actually changes. The advanced load parameters (urdf_param_name,srdf_param_name,http_file_server_base_url) moved to a newMoveIt Planner Optionscomponent, so the default case is justRosClient → MoveIt Planner. UseDeconstruct Plannerto recover the loaded cell / model when needed. - Reorganised the API reference into three groups that match the public-API surface: Core (
compas_fab.robots,compas_fab.backends,compas_fab.utilities,compas_fab.scene) and Integrations (compas_fab.blender,compas_fab.ghpython,compas_fab.rhino) hold the classes end users call, while Extending compas_fab gathers the contributor material — the Backend architecture guide, the backend interfaces and per-backend*.backend_featuresAPI pages, and the Grasshopper-component / icon-system / ActionChain notes (the former "Developer guide" section). Withinherited_membersenabled, each planner on thecompas_fab.backendspage now documents its full FK/IK/motion-planning method set directly (the methods it composes through multiple inheritance), so the feature mixins no longer need to be front-and-centre. The redundant per-backend pages (compas_fab.backends.ros/.pybullet/.kinematics) were removed — they were ~95–100% duplicates of thecompas_fab.backendsaggregator — andAnalyticalKinematicsandAnalyticalKinematicsClientare now re-exported fromcompas_fab.backendsso they remain documented in Core. - Unified the collision-checking option key across backends to
check_collision(defaultTrue= collision-free solutions only). PreviouslyMoveItInverseKinematicsusedallow_collision(inverted semantics) while the PyBullet/analytical backends already usedcheck_collision. The MoveIt feature now accepts the legacyallow_collisionkey as a backward-compatible alias — whencheck_collisionis unset andallow_collisionis present, the latter is inverted and used — so existing callers and thedocs/backends/ros/files/04_ik_allow_collision.pyexample continue to work unchanged. The newCf_InverseKinematicscheck_collisionboolean input passes straight through with no UI-layer translation. - Changed the default HTTP file server port used by
RosClient.load_robot_cell(andHttpFileServerLoader) from9091to9190. The previous default collided with the rosbridge port9091commonly used when remapping a ROS 2 stack to coexist with a ROS 1 stack (rosbridge9090+ ROS 2 rosbridge9091), causing HTTP 404s when the loader hit the bridge instead of the file server.9190stays clear of the 909x cluster while remaining mnemonic. Thedocker-compose-ros2.ymltest stack and theros2-ur10e-demoreference stack both defaultROS2_HTTP_PORTand the container-internal port to9190to match. - Standardized every backend page (
docs/backends/{analytical,analytical_pybullet,pybullet,ros,ros2}.md) to a common structure: When to use → Trade-offs → Setup → First example (embedded) → More examples (linked) → API reference. Each page now embeds one runnable example fromdocs/backends/*/files/viapymdownx.snippetsand links the remaining ~50 examples to GitHub. - Rewrote
docs/backends/index.mdas a real decision guide: a "by intent" table keyed by what the user wants to do (rather than backend name), plus a "by capability" matrix and explicit setup-cost summary. Linked from both Home and Installation. - Split
docs/installation.mdinto a focused library-install page (uv/pip/conda + verify) and a newdocs/frontends.mdcovering CAD environment setup (Rhino 8, Grasshopper, Blender, COMPAS Viewer, headless). The new front-ends page also documents which CAD environments work with which backends, surfacing the limitation that PyBullet cannot run inside Rhino's interpreter. - Rebranded the old
tutorial.mdasconcepts.md: a backend-agnostic walkthrough of the data model (RobotCell,RobotCellState,Target/Waypoints,TargetMode). No planner calls, the concepts page now reads as "this is the data; backends are how you execute it" and links out to the backends section for the actual planning calls. - Rewrote
docs/index.mdas a real landing page (was a 1-paragraph blurb): leads with the five-backend table, "I want to..." quick links, and a four-step what's-next list. Updated MkDocs nav to surface the new structure (Home → Installation → CAD front-ends → Concepts → Backends → API → Developer guide). - Bumped
compas_robotsrequirement from>=0.6,<1to>=1,<2. - Migrated packaging to
pyproject.toml. - Cleaned up
requirements-dev.txt. - Python classifiers trimmed to 3.9 (minimum, required for Rhino 8) and 3.13 (latest).
- Unpinned
roslibpyfrom1.8.1to>=2.0,<3in preparation for ROS 2 support. - Updated
ActionClientandGoalimports fromroslibpy.actionlibtoroslibpy.ros1.actionlibfollowing the breaking namespace change inroslibpy2.x. - Changed CI workflow for IronPython.
- Updated compas requirement to > 2.3
- Changed
clientparameter inPlannerInterface(client)to default toNone. - Changed
PlannerInterface.clientto a read-only property. - Moved
PlannerInterfacefrombackends/interfaces/client.pytobackends/interfaces/planner.py - Moved
AnalyticalInverseKinematicsto be a backend feature ofAnalyticalKinematicsPlanner. - Moved
AnalyticalPlanCartesianMotionto be a backend feature ofAnalyticalKinematicsPlanner. - Change backend features to use multi-inherence instead of
__call__to include the backend functions. - Changed parameters of
compas_fab.backends.SetRobotCell.set_robot_cell()to acceptRobotCellandRobotCellState. - Changed parameters of
compas_fab.backends.SetRobotCellState.set_robot_cell_state()to acceptRobotCellState. - Changed parameters of
compas_fab.backends.ForwardKinematics.forward_kinematics()to acceptRobotCellState,TargetModeandscale. - Changed parameters of
compas_fab.backends.InverseKinematics.inverse_kinematics()to acceptTargetandRobotCellState. - Changed parameters of
compas_fab.backends.InverseKinematics.iter_inverse_kinematics()to acceptTargetandRobotCellState. - Changed parameters of
compas_fab.backends.PlanMotion.plan_motion()to acceptTargetandRobotCellState. - Changed parameters of
compas_fab.backends.PlanCartesianMotion.plan_cartesian_motion()to acceptWaypointsandRobotCellState. - Changed
compas_fab.robots.BoundingVolumeto inherit fromcompas.data.Data. - Changed
compas_fab.robots.Constraintto inherit fromcompas.data.Data. - Changed
compas_fab.robots.JointConstraintto inherit fromcompas.data.Data. - Changed
compas_fab.robots.OrientationConstraintto inherit fromcompas.data.Data. - Changed
compas_fab.robots.PositionConstraintto inherit fromcompas.data.Data. - Moved
Robot.orientation_constraint_from_frame()toOrientationConstraint.from_frame(). - Moved
Robot.position_constraint_from_frame()toPositionConstraint.from_frame(). - Moved
Robot.constraints_from_frame()to non-exposedcompas_fab.backends.ros.backend_features.convert_target_to_goal_constraints(). - Changed
avoid_collisionsparameter inplan_motiontoallow_collisionsparameter. - Fixed error in
PyBulletForwardKinematics.forward_kinematicswhere function would crash ifoptionswas not passed. - Fixed error in
PyBulletInverseKinematics._accurate_inverse_kinematicswhere threshold was not squared for comparison. - Changed the behavior of
Durationclass when accepting both seconds (float) and nanoseconds (int) where the decimal point of seconds and the nanoseconds add up to more than 1 second. - Changed GH Component
ConstraintsFromPlanetoFrameTargetFromPlane. - Changed GH Component
ConstraintsFromTargetConfigurationtoConfigurationTarget. - Changed
RosClientconstructor to take a type for planner backend instead of a string. This also changes the name of the argument fromplanner_backendtoplanner_type. - Changed type-hints from comment-style to standard Python 3.x type-hints
- Changed
RosDistroto be an enum instead of string. - Changed
TargetModeto be an enum instead of string. - Changed default values for number of planning attempts in MoveIt to 5, and the allowed planning time to 1 second.
- Changed cartesian motion planner of MoveIt to raise an exception (including the partial trajectory) if fraction is below 1.0 (ie. the trajectory is not possible).
- Changed
PyBulletClient.connect()andPyBulletClient.disconnect()to take averboseparameter. - Changed
PyBulletClient._handle_concavity()to ignore theredirect_stdoutcontext manager to avoid the mysteriousWinError 6: The handle is invalid.error.
Fixed¤
Plan MotionandPlan Cartesian MotionGrasshopper components raised aNullReferenceExceptionwhen planning failed with no trajectory: the visualization helper (and, for Cartesian, thefractionread) dereferenced aNonetrajectory instead of just flagging the component. Both now short-circuit on aNonetrajectory and output empty geometry.- The PyBullet backend raised
NameError: name 'pybullet' is not definedwhenever the realpybulletmodule had already been imported elsewhere in the process (e.g. the user doesimport pybulletin the same Grasshopper script). The lazy-loader guard incompas_fab.backends.pybullet.clientonly bound thepybulletname when the module was not yet imported — being already insys.modulesnever created the local binding. It now binds the (cached) real module in that case. - Auto-created Grasshopper dropdowns and boolean toggles (
ensure_value_list/ensure_boolean_toggle) duplicated themselves on every recompute, stacking 2–4 value lists on eachtarget_modeinput and extra toggles onload_geometry. The widget was added withAddObject/AddSourceinline during the running solution, which doesn't commit until the solution ends, so follow-up solves still readSourceCount == 0and added another. Creation now happens inside theScheduleSolutioncallback (between solves, where the wire commits), guarded by a sticky pending flag, so exactly one widget is ever added. - The
Visualize Robot CellGrasshopper component failed with aNoneerror when nocell_statewas wired: it reads theRobotCellObject's child scene objects directly, but those are only built when a state is applied viaupdate(), which was skipped for an unwired state. It now falls back to the cell'sdefault_cell_state(), drawing the cell in its default configuration. RigidBodyLibrary.floor()built a flat plane atZ=0, which collided with the robot base under distance-0 collision checking and made every configuration fail (so e.g. PyBullet IK with a floor returned no solutions). A robot base's collision geometry can dip several millimetres below the origin (the UR5base_link_inertiareaches about -7 mm), sofloor()now takes aclearanceparameter and sits belowZ=0by default (1 cm). Adding the base link to the floor'sRigidBodyState.touch_linksremains the robot-agnostic alternative.- Outgoing ROS message headers were not JSON-serializable under
roslibpy2.0, breaking everyMoveItPlanner.set_robot_cell(and any other header-carrying message) withTypeError: Object of type Time is not JSON serializable.roslibpy2.0 wraps a header'sstampin aUserDict-basedroslibpy.core.Time, whichjson.dumpsrejects;compas_fab'sstd_msgs.Header.msg/format_header_for_distrobuild outgoing headers viadict(roslibpy.Header(...)), embedding thatTime. Both now flatten the roslibpy header (and its nestedstamp) to plaindicts via a new_to_plainhelper, keeping roslibpy's per-distro field shaping while emitting only JSON-native types. Regression-tested intests/backends/ros/messages/test_std_msgs.py::test_header_msg_is_json_serializable. PyBulletClientcould not be used outside awithblock:_cache_dirwas only created in__enter__, so callingconnect()directly left itNoneand every mesh/tool/URDF load failed withAttributeError: 'NoneType' object has no attribute 'name'._cache_diris now a lazily-created property (theTemporaryDirectoryis made on first access and still cleaned up on__exit__), so the client works whether or not it is used as a context manager — which is how the GrasshopperPyBullet Clientcomponent drives it.redirect_stdout(used throughout the PyBullet backend to silence native output) calledsys.stdout.fileno()unconditionally, raisingio.UnsupportedOperation: filenoinside embedded interpreters whose stdout has no OS-level file descriptor — e.g. Rhino 8's CPython, breakingPyBulletClient.connect()there. It already special-cased pytest and ipykernel for the same reason; it now also skips the fd-level redirect wheneverfileno()is unavailable, so the PyBullet backend (and its new Grasshopper components) run in Rhino.AnalyticalPybulletInverseKinematics._iter_inverse_kinematics_frame_targetwas silently dropping every collision-free IK candidate. Thetry/except CollisionCheckErrorblock had noelsebranch — when the collision check passed (no exception), the configuration was never yielded. Added the missingelse: yield configuration. Verified end-to-end with the03_iter_ik_pybullet.pyexample, which now returns 6 valid + 2 colliding configurations (was: 0 valid + all 8 reported as colliding).AnalyticalInverseKinematics.iter_inverse_kinematicsand its_iter_inverse_kinematics_frame_targethelper hadgroup: Optional[str]declared without a default, while the parentInverseKinematicsinterface and all example usages treatgroupas optional. Added= Noneso calls likeplanner.iter_inverse_kinematics(target, start_state)work as documented.- Cleared stale docstring parameters across
compas_fab.backendsinterfaces and backend feature implementations (robot,client,solver,planner_type) that no longer matched their signatures, plus a confusingly-indented continuation line inRigidBodyState.attached_to_link.invoke docsnow builds with zero warnings. - Fixed three analytical/PyBullet examples that crashed at startup due to cell-state desync after objects were added to the cell:
docs/backends/analytical_kinematics/files/02_inverse_kinematics with_tools.py: now refreshes the state from the cell after adding the cone tool.docs/backends/analytical_kinematics/files/03_analytical_pybullet_planner.py: rewritten to use the pre-configuredRobotCellLibrary.abb_irb4600_40_255_printing_tool()cell (which has the correcttouch_linkssemantics) and derives its target frame via FK from a chosen seed pose. Was previously crashing onKeyError: 'cone'and then yielding 0 IK solutions even after that.docs/backends/pybullet/files/04_ik_semi_constrained.py: now creates thetarget_markerrigid body state explicitly (was crashing onKeyError: 'target_marker').docs/backends/analytical_kinematics/files/03_iter_ik_pybullet.py(already covered above) now derives its target via FK for clarity.docs/backends/analytical_kinematics/files/04_cartesian_path_analytic_pybullet.pynow has a comment noting thatmatplotlibis an optional dependency that must be installed separately.- All analytical-backend examples now import solver classes (
UR5Kinematics,ABB_IRB4600_40_255Kinematics) fromcompas_fab.backends(the public top-level path), not the privatecompas_fab.backends.kinematics.solvers. MoveItPlanMotion.plan_motionandMoveItPlanCartesianMotion.plan_cartesian_motionwere re-raising every typed planner error (MPNoPlanFoundError,MPStartStateInCollisionError, …) wrapped inRosValidationError, so callers catchingMotionPlanningErroras documented were missing every real failure. Both methods now unwrapRosValidationErrorand re-raisee.original_exception, matchingMoveItInverseKinematics.iter_inverse_kinematics.JointTrajectoryPoint.joint_nameswas empty on points produced by the MoveIt and analytical Cartesian planners — the ROS message spec only carries names on the parentJointTrajectory, and the analytical path simply forgot. Both backends now attach the trajectory'sjoint_namesper point at construction, matching PyBullet. Any consumer that walks points by name (the GH viz helper,Cf_DeconstructTrajectory) was silently FK-ing the start state for every point.ToolLibrary.cone()was not initializing a link on the underlyingToolModelwhenload_geometry=False, which left the tool's robot tree malformed and made any downstreamiter_joints()/get_configurable_joints()call raiseAttributeError: 'NoneType' object has no attribute 'joints'. As a resultRobotCellLibrary.ur5_cone_tool(load_geometry=False)always crashed. The factory now callsadd_link("cone_link", visual_meshes=[...], collision_meshes=[...])(mirroringToolLibrary.printing_tool()) so the model is structurally valid in both geometry modes.- Eliminated intermittent CI failures in
integration.ymlon theRosClientdoctest underpytest --doctest-modulesthat raisedRosTimeoutError('Failed to connect to ROS'). Both>>> with RosClient() as client:examples incompas_fab.backends.ros.client(theRosClientclass docstring at line 162 andRosClient.load_robot_cellat line 257) are now marked# doctest: +SKIP— they remain as readable illustrations of the API but no longer run as live integration tests. The actual code path is exercised bytests/backends/ros/test_ros_client.py(9 cases against a module-scopedros1_clientfixture, never observed to flake). Earlier hypotheses — cold rosbridge startup (reverted in2ffc37fac) and a roslibpy 2.x reactor lifecycle issue (validated against gramaziokohler/roslibpy@lifecycle-fixes via a temporaryrequirements.txtpin) — both failed to eliminate the flake, falsifying them; the root cause appears to be an interaction between doctest's evaluation context and roslibpy's twisted reactor that only the first>>> with RosClient()after the test-fixture suite triggers (the second such doctest always succeeds).
Removed¤
- All Sphinx-era documentation sources: every
docs/**/*.rst, thedocs/conf.pySphinx config, thedocs/_static/anddocs/_images/asset folders, thedocs/developer/generated/autosummary output,docs/spelling_wordlist.txtanddocs/doc_versions.txt(the latter superseded bymike's gh-pages versioning). .. autosummary::,.. toctree::and.. currentmodule::directives from all module-level__init__.pydocstrings (replaced with prose + intra-doc Markdown links resolved bymkdocstrings).- Removed
DirectUrActionClientand associateddirect_urmessages module since this UR-specific action client was outdated and unused. - Removed support for Python '3.8'.
- Removed
compas_fab.backends.CollisionError. - Removed
compas_fab.backends.AddCollisionMeshfrom backend features. - Removed
compas_fab.backends.AppendCollisionMeshfrom backend features. - Removed
compas_fab.backends.RemoveCollisionMeshfrom backend features. - Removed
compas_fab.backends.AddAttachedCollisionMeshfrom backend features. - Removed
compas_fab.backends.RemoveAttachedCollisionMeshfrom backend features. - Removed
compas_fab.backends.ClientInterface.plannerattribute. - Removed
compas_fab.backends.ClientInterface.inverse_kinematics(). - Removed
compas_fab.backends.ClientInterface.forward_kinematics(). - Removed
compas_fab.backends.ClientInterface.plan_cartesian_motion(). - Removed
compas_fab.backends.ClientInterface.plan_motion(). - Removed
compas_fab.backends.ClientInterface.get_planning_scene(). - Removed
compas_fab.backends.ClientInterface.reset_planning_scene(). - Removed
compas_fab.backends.ClientInterface.add_collision_mesh(). - Removed
compas_fab.backends.ClientInterface.remove_collision_mesh(). - Removed
compas_fab.backends.ClientInterface.append_collision_mesh(). - Removed
compas_fab.backends.ClientInterface.add_attached_collision_mesh(). - Removed
compas_fab.backends.ClientInterface.remove_attached_collision_mesh(). - Removed
compas_fab.backends.pybullet.backend_features.PyBulletAddAttachedCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.PyBulletAddCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.PyBulletAppendCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.PyBulletRemoveAttachedCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.PyBulletRemoveCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.MoveItAddAttachedCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.MoveItAddCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.MoveItAppendCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.MoveItRemoveAttachedCollisionMesh. - Removed
compas_fab.backends.pybullet.backend_features.MoveItRemoveCollisionMesh. - Removed
compas_fab.backends.PyBulletClient.collision_objectsattribute. - Removed
compas_fab.backends.PyBulletClient.attached_collision_objectsattribute. - Removed
compas_fab.backends.PyBulletClient.load_ur5(). - Removed
compas_fab.backends.PyBulletClient.load_robot(). - Removed
compas_fab.robots.AttachedCollisionMesh. - Removed
compas_fab.robots.CollisionMesh. - Removed
compas_fab.robots.PlanningScene. - Removed
compas_fab.robots.Robot. (UseRobotCellinstead) - Removed
compas_fab.robots.RobotLibrary. (UseRobotCellLibraryinstead) - Removed
compas_fab.robots.Tool. (UseToolModeldirectly inRobotCellinstead) - Removed
compas_fab.robots.Robot.transformed_frames. (use the one inRobotModelinstead) - Removed
compas_fab.robots.Robot.transformed_axes. (use the one inRobotModelinstead) - Removed
compas_fab.robots.Robot.merge_group_with_full_configurationas it can be covered byConfiguration.merged. - Removed
compas_fab.robots.Robot.get_position_by_joint_nameas Configuration class can now be directly accessed by joint name. - Removed
compas_fab.robots.Robot.get_group_names_from_link_nameas it is too oddly specific. - Removed
compas_fab.robots.JointTrajectory.attached_collision_meshesattribute from `` class. - Removed
inverse_kinematics,plan_cartesian_motion, andplan_motionmethods from Robot, access them using the planner instead. - Removed
plan_cartesian_motion_deprecatedandplan_motion_deprecatedmethods fromRobotclass - Removed
forward_kinematics_deprecatedandinverse_kinematics_deprecatedmethod fromRobotclass - Removed
compas_fab.sensorsmodule. - Removed support for IronPython.
[1.1.0] 2025-04-17¤
Added¤
Changed¤
- Made
pybulletentirely optional. To installpybullet, usepip install compas_fab.[pybullet]or installpybulletmanually.
Removed¤
[1.0.5] 2025-04-17¤
Added¤
Changed¤
- Rhino CPython support: change
pybulletto be optional requirements inside Rhino.
Removed¤
[1.0.4] 2025-04-15¤
Added¤
Changed¤
Removed¤
[1.0.3] 2025-04-15¤
Added¤
- Added helper function
messagetocompas_fab.ghpython.components. - Added helper function
errortocompas_fab.ghpython.components. - Added helper function
remarktocompas_fab.ghpython.components. - Added helper function
warningtocompas_fab.ghpython.components. - Added GH component definitions compatible with CPython in Rhino8.
Changed¤
- Updated dev dependency to
compas_invocations2. - Fixed
AttributeErrorininverse_kinematics_spherical_wrist(). - Fixed
AttributeErrorin VisualizeRobot GH component.
Removed¤
- Removed
create_idfromcompas_fab.ghpython.components, usingcompas_ghpython.create_idinstead.
[1.0.2] 2024-02-22¤
Added¤
Changed¤
- Raise
BackendFeatureNotSupportedErrorexceptions when a features is not supported by the planner, instead of genericException.
Removed¤
[1.0.1] 2024-02-20¤
Added¤
Changed¤
Removed¤
[1.0.0] 2024-02-20¤
Added¤
- Add parameter to control which link the tool is connected to in Grasshopper.
- Introduced
compas_fab.robots.RobotLibraryclass with 4 built-in robots. - Added a script to extract URDF, SRDF and meshes from a Docker MoveIt instance.
Changed¤
- Changed
CollisionMeshinherit fromcompas.data.Data - Changed
AttachedCollisionMeshto inherit fromcompas.data.Data - Changed
Robotinherit fromcompas.data.Data - Changed
RobotSemanticsinherit fromcompas.data.Data - Changed
Toolto inherit fromcompas.data.Data - Renamed
Tool.link_nametoTool.connected_to - Migrate to COMPAS 2.x: add dependency to
compas_robots - Migrate to COMPAS 2.x: use
compas.tolerancemodule instead ofcompas.PRECISION - Add
attributestoTrajectoryclass. - Fixed
dataserialization API to comply withCOMPAS 2.0private data API. - Use the tool's
connected_tolink when showing end-effector frames in Grasshopper. - Change default end-effector link name from
ee_linktotool0.
Removed¤
- Removed V-Rep backend.
- Removed outdated
PathPlanclass. - Removed outdated rfl demo class.
- Remove deprecated aliases for artists (currently on
compas_robots). - Removed
compas_fab.robots.ur5because it is now part ofcompas_fab.robots.RobotLibrary. - Removed data files of ur5 and ur10e from
src/compas_fab/data/universal_robotsbecause they are now in ofsrc/compas_fab/data/robot_library.
[0.28.0] 2023-05-10¤
Added¤
- Added
Forward KinematicsGH component.
Changed¤
- Updated install process of GH components.
- Added caching to the GH component that visualizes scene, to avoid retrieving the whole scene too often.
Fixed¤
- Fixed pre-Noetic support on the MoveIt planner when a tool is attached to the robot.
0.27.0¤
Added¤
- Added support for attached and non-attached collision mesh visualization to the
Robot VisualizeGH component. - Added a prefix to all GH components.
- Added
appendto the operations of theCollision MeshGH component.
Changed¤
- Changed behavior of
Attach ToolGH component to only attach the tool but not add it to the planning scene state. - Duration class takes floats as
secvariable. - Changed the behavior of
forward_kinematics,inverse_kinematics,iter_inverse_kinematics,plan_cartesian_motionand constraints construction methods (orientation_constraint_from_frame,position_constraint_from_frame,constraints_from_frame) inRobotclass to use the frame of the attached tool if a tool is attached. This behavior can be reverted back (ie. only calculate T0CF) using the flaguse_attached_tool_frameof all these methods. - Fixed usage of
tangent_points_to_circle_xyin Spherical Wrist solver to work with COMPAS v1.16 and older.
Fixed¤
- Fixed DH params for analytical IK solver of UR3e and UR10e.
- Fixed Kinetic support on IK, FK, and motion planning calls.
- Fixed
Publish to topicGrasshopper component when theros_clienthas been replaced (eg. disconnected and reconnected).
Deprecated¤
Removed¤
0.26.0¤
Added¤
- Added a new GH component -
ConstraintsFromTargetConfiguration - Added some missing information to GH and V-REP docs.
- Added a
Robot().attached_toolsproperty to allow attaching tools to multiple planning groups simultaneously.
Changed¤
- Replaced icon for GH component -
ConstraintsFromPlane Robot().attached_toolnow points to the tool attached to therobot.main_group_name.- Added parameter
groupto theAttachToolComponent
Fixed¤
- Attaching a tool to a planning group doesn't overwrite the tool attached to other groups.
- Changed
Trajectoryto inherit fromcompas.data.Dataclass to fix a serialization error that expects guid to be present.
Deprecated¤
Removed¤
0.25.0¤
Changed¤
- Changed Grasshopper components to default to icon display.
- Changed to use
compas_rhino.conversionsto coerce frames.
Fixed¤
- Fixed link parameter name when doing FK inside the GH component to display attached collision meshes.
- Fixed transform of the attached collision mesh frame inside the GH component.
- Fixed uninstall process not removing GH components.
0.24.0¤
Added¤
- Added
compas_fab.robots.ReachabilityMap - Added
compas_fab.robots.DeviationVectorsGenerator - Added
compas_fab.robots.OrthonormalVectorsFromAxisGenerator
Changed¤
Fixed¤
- Fixed
ROSmsgimport on GH components for publish/subscribe.
Deprecated¤
Removed¤
0.23.0¤
Added¤
- Added
compas_fab.backends.PyBulletClient.load_ur5()method to simplify some examples. - Added Grasshopper components to get a zero configuration and to merge two configurations.
Changed¤
- Moved all public API classes in
compas_fab.backendsto second-level imports. - Updated to COMPAS 1.14.
- Simplified call to remove an attached tool by also removing the remaining collision mesh from the world automatically.
Fixed¤
- Fixed PyBullet loading of meshes.
- Fixed missing flag in reset planning scene call.
- Fixed issue on cartesian and kinematic planning when model contains passive joints.
- Fixed pose of collision mesh in ROS Noetic being ignored.
Deprecated¤
- Deprecated
compas_fab.utilities.write_data_to_jsonin favor ofcompas.data.json_dump. - Deprecated
compas_fab.utilities.read_data_from_jsonin favor ofcompas.data.json_load.
Removed¤
0.22.0¤
Added¤
- Added
Attach ToolGH component: crowd-coded at McNeel's Robotic Fabrication Workshop!
Changed¤
Fixed¤
Deprecated¤
Removed¤
0.21.1¤
Added¤
Changed¤
- Changed default wire visibility to hidden in some GH components for cleaner Grasshopper files.
Fixed¤
Deprecated¤
Removed¤
0.21.0¤
Added¤
- Added a new backend: analytical kinematics for spherical-wrist and offset-wrist robots.
Fixed¤
- Consider
AttachedCollisionMeshinAnalyticalInverseKinematics.
0.20.1¤
Removed¤
- Removed the bundled binary files for the
VrepClientremote API. To use V-REP, use theremoteApibinaries provided with the software.
0.20.0¤
Added¤
- Added
PoseArray,MultiArrayDimension,MultiArrayLayout,Int8MultiArray,Float32MultiArray,Int32tocompas_fab.backends.ros.messages - Added
unordered_disabled_collisionsattribute toPyBulletClientandRobotSemantics - Added better support for concave meshes in the
PyBulletClient - Added
Robot.iter_inverse_kinematicsto allow iterating over all IK solutions provided by a solver
Changed¤
- Changed the backend feature
InverseKinematics.inverse_kinematicsto be a generator. As a consequence of this,ClientInterface.inverse_kinematicsandPlannerInterface.inverse_kinematicshave changed to generators as well - Standardized the yielded type of
InverseKinematics.inverse_kinematicsacross the PyBullet, MoveIt and V-REP planners - Added iterative accurate IK resolution for PyBullet
Fixed¤
- Fixed
UnsupportedOperationerror when usingPyBulletClientin Jupyter notebook (raised byredirect_stdout) - Fixed
JointTrajectoryPoint.from_datato be backward-compatible with JSON data generated beforecompas_fab0.18 - Fixed
JointTrajectory.from_datato be backward-compatible with JSON data generated beforecompas_fab0.17
Deprecated¤
Removed¤
0.19.1¤
Added¤
Changed¤
Fixed¤
- Fixed bundling of ghuser components
Deprecated¤
Removed¤
0.19.0¤
Added¤
- Added documentation for Grasshopper components.
- Added Grasshopper components to publish and subscribe to ROS topics.
Changed¤
- Updated
build-ghuser-componentstask - Updated to COMPAS 1.7
Fixed¤
Deprecated¤
Removed¤
0.18.3¤
Added¤
Changed¤
- Made consistent use of
reprin nested objects
Fixed¤
- Fixed bug in
compas.backends.PyBulletClient.convert_mesh_to_bodycircumventing PyBullet's propensity to cache
Deprecated¤
Removed¤
0.18.2¤
Added¤
Changed¤
Fixed¤
Deprecated¤
Removed¤
0.18.1¤
Fixed¤
- Fix error message during uninstall of Grasshopper components
0.18.0¤
Added¤
- Grasshopper components now also for Mac
- Added support for MoveIt on ROS Noetic
- Added support for Python 3.9
Changed¤
- The
Configurationclass has moved tocompas.robots, but is still aliased withincompas_fab.robots - Lazily load
V-REP remoteApilibrary
Fixed¤
- Fixed
repr()ofROSmsgclass - Fixed data type of secs and nsecs in
TimeROS message - Fixed
CollisionObject.to_collision_meshes - Fixed serialization of joint names for
compas_fab.robots.JointTrajectoryPoint - Fixed deserialization of
AttachedCollisionMesh
Deprecated¤
compas_fab.robots.Configurationis being deprecated in favor ofcompas.robots.Configuration
0.17.0¤
Added¤
- Added python components library for Grasshopper
- Added
compas_fab.robots.PyBulletClient.get_robot_configuration - Added
compas_fab.robots.Robot.ensure_geometry - Added serialization methods to
compas_fab.robots.CollisionMeshandcompas_fab.robots.AttachedCollisionMesh - Added
attached_collision_meshesattribute tocompas_fab.robots.JointTrajectory - Added
compas_fab.backends.PlanningSceneComponents.__ne__ - Added dictionary behavior to
compas_fab.robots.JointTrajectoryPoint.merge - Added length limitations to attributes of
compas_fab.robots.JointTrajectoryPoint.merge
Changed¤
- Updated to
COMPAS 1.1 Configuration&JointTrajectoryPoint: the attributesvaluesandtypeschanged tojoint_valuesandjoint_typesrespectively.
Fixed¤
- Fixed bug in the PyBullet client where one could not update the configuration of a robot with an attached collision mesh
- Fixed bug existing since version 0.12 where
compas_fab.backends.RosClient.add_attached_collision_meshadded collision objects to the scene, but did not attached them to the robot - Fixed bug when keys with
Nonevalues were passed to the planner.
Deprecated¤
Removed¤
- Remove
compas_fab.robots.JointTrajectoryPoint.merge
0.16.0¤
Changed¤
- Updated to
COMPAS 1.0
0.15.0¤
Added¤
Changed¤
- Updated to
COMPAS 0.19
Fixed¤
Deprecated¤
Removed¤
0.14.0¤
Added¤
- Added new backend feature
ResetPlanningScene - Added
MoveItResetPlanningScene
Changed¤
- Updated to
COMPAS 0.18 - Use
compas.IPYto check for IronPython
Fixed¤
- Fixed bug in
remove_attached_toolofPlanningScene
0.13.1¤
Added¤
- Added
nameproperty toToolclass.
Fixed¤
- Fixed bug in
add_attached_toolofPlanningScene - Fixed
frame_idgeneration when tool name changes - Fixed freeze with some sync planning scene methods on Grasshopper/IronPython
0.13.0¤
Changed¤
- Updated to
COMPAS 0.17
0.12.0¤
Added¤
- PyBullet integration: added support for PyBullet client and forward/inverse kinematic solver
- Added
ClientInterface,PlannerInterfaceand various backend feature interfaces - Added implementations of these interfaces for ROS and V-REP
- Added
attributesdictionary toRobotclass - Added
compas_fab.robots.Tool.from_t0cf_to_tcf - Added
compas_fab.robots.Tool.from_tcf_to_t0cf - Added
joint_namesas optional parameter for allcompas_fab.robots.Configurationconstructors - Added
compas_fab.robots.Configuration.iter_differences - Added
compas_fab.robots.Configuration.max_difference - Added
compas_fab.robots.Configuration.close_to - Added
compas_fab.robots.Configuration.merge - Added
compas_fab.robots.JointTrajectoryPoint.merge - Added
compas_fab.robots.Semantics.group_states - Added
compas_fab.robots.Robot.get_configuration_from_group_state
Changed¤
- Updated to
COMPAS 0.16.9 - Renamed
compas_fab.robots.Robot.to_local_coordstocompas_fab.robots.Robot.to_local_coordinates - Renamed
compas_fab.robots.Robot.to_world_coordstocompas_fab.robots.Robot.to_world_coordinates - Backend clients have been restructured according to the new interfaces
- Parameter
backendof forward kinematics has been renamed tosolver - The signatures of all kinematics, motion planning and planning scene management methods have been homogenized across backend clients and within
Robot - All examples have been updated to reflect these changes
- The installer to Rhino has been unified with COMPAS core. Now running
python -m compas_rhino.installwill also detect and install COMPAS FAB and its dependencies. - Renamed all
RobotArtistimplementations toRobotModelArtistto reflect the fact they depend oncompas.robots.RobotModel. - Renamed
compas_fab.robots.Robot.from_tool0_to_attached_tooltocompas_fab.robots.Robot.from_t0cf_to_tcf - Renamed
compas_fab.robots.Robot.from_attached_tool_to_tool0tocompas_fab.robots.Robot.from_tcf_to_t0cf - Changed ROS planning scene methods to be synchronous.
Fixed¤
- Attached collision meshes are included in inverse kinematics calculations in ROS
Deprecated¤
- The methods
forward_kinematics,inverse_kinematics,plan_cartesian_motionandplan_motionofRobotclass have been refactored, but a backwards-compatible deprecated version with the old signatures still exists suffixed by_deprecated, e.g.forward_kinematics_deprecated. RobotArtistare deprecated in favor ofRobotModelArtist.
Removed¤
0.11.0¤
Added¤
- Added optional
joint_namestoConfiguration - Added
Configuration.scaled - Added
full_joint_statetoRobot.inverse_kinematics - Added
Semantics.get_all_configurable_joints
Changed¤
- Updated to
COMPAS 0.15 - Construct
full_configurationwithvalues,types,joint_namesinRobotrather than inMoveItPlanner MoveItPlannerreturnsstart_configurationwith setjoint_names- Removed parameter
namesfromRobotArtist.update - Updated Grasshopper examples
Robot:forward_kinematicsreturns nowframe_WCFMoveItPlanner:forward_kinematicstakes now instance ofConfigurationandrobotMoveItPlanner:inverse_kinematicstakes now instance ofConfigurationandrobot- Property :class:
compas_fab.robots.Robot.artistdoes not try to scale robot geometry if links and/or joints are not defined. - In :class:
compas_fab.robots.constraints.JointConstraint, addedtolerance_aboveandtolerance_belowfor allowing asymmetrical constraints. - In :class:
compas_fab.robots.Robot, changed theconstraints_from_configurationfunction withtolerances_aboveandtolerances_below. - :meth:
compas_fab.robots.CollisionMesh.scalenow takes a scale factor instead of a :class:compas.geometry.Scaleinstance as an argument.
Fixed¤
- Convert constraints on inverse kinematics and cartesian planner to ROS messages
- Fix support for trajectory constraints on kinematic planner
0.10.2¤
Added¤
- Added Python 3.8 support
Changed¤
- Updated to
COMPAS 0.13
0.10.1¤
Fixed¤
- Fix DAE parser to handle
polylistmeshes - Bumped
roslibpydependency to0.7.1to fix blocking service call issue on Mac OS
0.10.0¤
Added¤
- Added
attach_tool,detach_tool,draw_attached_tool,from_tool0_to_attached_toolandfrom_attached_tool_to_tool0toRobot - Added
attach_toolanddetach_tooltoArtist - Added
add_attached_toolandremove_attached_tooltoPlanningScene - Added redraw/clear layer support to :class:
~compas_fab.rhino.RobotArtistfor Rhino - Added material/color support for DAE files on ROS file loader
Changed¤
- Changed
inverse_kinematics,plan_cartesian_motionandplan_motionto use the attached_tool'sAttachedCollisionMeshif set
Fixed¤
- Fixed mutable init parameters of
Configuration,JointTrajectoryPoint,JointTrajectoryandRobot.basic. - Fixed interface of :class:
~compas_fab.blender.RobotArtistfor Blender - Fixed DAE parsing of meshes with multiple triangle sets
0.9.0¤
Added¤
- Added
load_robotmethod to ROS client to simplify loading robots from running ROS setup. - Added
compas_fab.robots.Wrench: a Wrench class representing force in free space, separated into its linear (force) and angular (torque) parts. - Added
compas_fab.robots.Inertia: a Inertia class representing spatial distribution of mass in a rigid body
Changed¤
- Updated to
COMPAS 0.11
0.8.0¤
Changed¤
- Updated to
COMPAS 0.10 - Add better support for passive joints on IK, Cartesian and Kinematic planning
Fixed¤
- Use WorldXY's origin as default for robots that are have no parent join on their base
- Fixed parsing of semantics (SRDF) containing nested groups
- Fixed DAE support on ROS File loader
0.7.0¤
Changed¤
- Fixed Python 2 vs Python 3 incompatibilities in
compas_fab.sensorsmodule - Changed example for loading PosConCM (includes parity argument, differs from PosCon3D)
- Changed format
compas_fab.sensors.baumer.PosConCM.set_flex_mount() - Changed tasks.py to run
invoke test - Renamed
compas_fab.backends.CancellableTasktocompas_fab.backends.CancellableFutureResult - ROS client: changed joint trajectory follower (
follow_joint_trajectory) to support genericJointTrajectoryarguments. - ROS client: changed return type of trajectory execution methods to
CancellableFutureResult
Added¤
- Added
compas_fab.sensors.baumer.PosCon3D.reset() - Added
compas_fab.sensors.baumer.PosConCM.reset() - ROS client: added support for MoveIt! execution action via
client.execute_joint_trajectory. - Added
compas_fab.backends.FutureResultclass to deal with long-running async tasks
Removed¤
- Removed
compas_fab.sensors.baumer.PosConCM.get_live_monitor_data() - Removed non-implemented methods from
compas_fab.robots.Robot:send_frame,send_configuration,send_trajectory
Fixed¤
- Fixed missing planner initialization when used without context manager.
0.6.0¤
Changed¤
- Updated
COMPASdependency to0.8.1 - Base robot artist functionality moved to
compas.robots.RobotModel Robot:inverse_kinematicsreturns now group configurationRobot:forward_kinematicshas new parameterbackendto select eitherclientFK ormodelFK.Robot:forward_kinematicsreturns nowframe_RCFRobot:forward_kinematicsdoesn't need full configuration anymore- Fixed delays when modifying the planning scene of ROS.
Added¤
- Added
jump_thresholdparameter toplan_cartesian_motion - Added
action_nameparameter to reconfigure joint trajectory follower action. - Added support to retrieve the full planning scene.
Removed¤
- Removed
compas_fab.Robot.get_configuration
0.5.0¤
Changed¤
- ROS Client: renamed
compute_cartesian_pathtoplan_cartesian_motion - ROS Client: renamed
motion_plan_goal_frameandmotion_plan_goal_configurationtoplan_motion - ROS Client: removed methods from
Robotthat are now handled withPlanningScene, e.g.add_collision_meshandadd_attached_collision_mesh - ROS Client: change the return type of
plan_motionandplan_cartesian_motionto the new trajectory classes. - ROS File Server Loader: moved to
compas_fab.backendspackage - ROS File Server Loader: renamed
loadtoload_urdfand sync'd API to other loaders. - V-REP Client: renamed
get_end_effector_posetoforward_kinematics - V-REP Client: renamed
find_robot_statestoinverse_kinematics - V-REP Client: renamed
find_path_plan_to_configtoplan_motion_to_config - V-REP Client: renamed
find_path_plantoplan_motion - V-REP Client: changed
is_connectedto become a property - Made
robot_artistdefaultNoneonRobotconstructor - Changed
PathPlanclass to use the new trajectory classes
Added¤
- Added
scalemethod toConfiguration - Implemented Constraints (
OrientationConstraint,PositionConstraint,JointConstraint) to use withplan_motion - Implemented
PlanningScene,CollisionMeshandAttachedCollisionMesh - Added generic representations for motion planning requests (
JointTrajectory,JointTrajectoryPoint,Duration) - Added UR5 robot model data for example purposes
- Added several doc examples
Removed¤
- Aliases for
FrameandTransformation. Import fromcompas.geometryinstead.
0.4.1¤
Fixed¤
- Fixed missing library for V-REP on macOS
Deprecated¤
- The aliases for
FrameandTransformationwill be removed, in the future, import directly fromcompascore.
0.4.0¤
Added¤
- Color parameter to Rhino robot artist
Changed¤
- Updated to
COMPAS 0.4.10
0.3.0¤
Added¤
- Deeper integration with MoveIt! motion planning services
- Added sync and async versions of many ROS service calls
- Added support for cancellable tasks/actions
Changed¤
- Renamed
UrdfImportertoRosFileServerLoader - Updated to
COMPAS 0.4.8
0.2.1¤
Added¤
- Robot artist for Blender
0.2.0¤
Added¤
- First open source release!
- V-REP and ROS clients
- Updated to
COMPAS 0.3.2
0.1.0¤
Added¤
- Initial version