agents.components.moveit#

Module Contents#

Classes#

MoveIt

This component provides classical, collision aware manipulation by driving a running MoveIt 2 move_group node.

API#

class agents.components.moveit.MoveIt(*, config: agents.config.MoveItConfig, component_name: str, inputs: Optional[List] = None, outputs: Optional[List] = None, **kwargs)#

Bases: agents.components.component_base.Component

This component provides classical, collision aware manipulation by driving a running MoveIt 2 move_group node.

The component runs as a ROS2 Action Server exposing the <component_name>/manipulate_with_moveit action, which takes a motion target and plans and executes a path to it. Six kinds of targets are supported, selected with the goal’s mode field (or inferred from the fields that are populated):

  • pose: an end-effector pose, planned with the configured planner and reached within the configured position/orientation tolerances.

  • joints: explicit joint positions.

  • named: a named target defined in the robot’s SRDF (e.g. “home”, “ready”), resolved to joint positions by reading the SRDF from the running move_group node.

  • cartesian: a straight-line end-effector path through a list of waypoints, computed with MoveIt’s Cartesian path service and executed only if enough of the path is achievable (see cartesian_fraction_threshold). Waypoints without an orientation preference (identity) hold the current end-effector orientation, read from move_group’s FK service — an arbitrary default may not be achievable, especially on underactuated arms.

  • pick: a full grasp sequence on a planning scene object, named with target_object (a scene id or detection label) or located by target_pose: approach above it, open the gripper, descend, close, attach the object and lift it.

  • place: the inverse sequence for the currently attached object: approach above target_pose, descend, open the gripper, detach (the object stays in the scene where released) and retreat.

Gripper control is available as component actions (open_gripper, close_gripper, set_gripper), either through the gripper planning group or through a gripper controller, based on the gripper_mode config parameter. All component actions and the action server itself are discoverable as tools by the Cortex component, making the manipulator directly usable by LLM agents.

This component requires a running move_group node, which is normally launched from the robot’s MoveIt configuration package. It can be brought up alongside the components in the same recipe (see the example below), and the moveit_msgs package must be installed (ros-<distro>-moveit-msgs).

Parameters:
  • config (MoveItConfig) – The configuration for the MoveIt component. arm_group_name is required and must match a planning group in the robot’s SRDF.

  • inputs (Optional[list[Topic]]) – Optional input topics for the component, limited to Detections3D type: detected objects used to populate the planning scene (see scene_update_mode in the config), so that motions plan around what the robot’s cameras see. Not required for manipulation.

  • outputs (Optional[list[Topic]]) – Optional output topics for the component. Not required for manipulation.

  • component_name (str) – The name of the MoveIt component.

  • kwargs – Additional keyword arguments.

Example usage:

from agents.components import MoveIt
from agents.config import MoveItConfig
from agents.ros import Launcher

config = MoveItConfig(
    arm_group_name="panda_arm",
    gripper_group_name="hand",
    max_velocity_scaling=0.2,
)
manipulator = MoveIt(config=config, component_name="manipulator")

launcher = Launcher()
# bring up the robot's MoveIt configuration alongside the component
launcher.include_launch_file(
    package="moveit_resources_panda_moveit_config", launch_file="demo.launch.py"
)
launcher.add_pkg(components=[manipulator])
launcher.bringup()

A motion goal can then be sent to the running component, e.g. from the command line:

ros2 action send_goal /manipulator/manipulate_with_moveit automatika_embodied_agents/action/MoveManipulator "{mode: named, named_target: ready}"

And the gripper can be commanded with:

ros2 service call /manipulator/execute_method automatika_ros_sugar/srv/ExecuteMethod "{name: open_gripper, kwargs_json: '{}'}"
create_all_action_clients()#

Create action clients to the move_group node

destroy_all_action_clients()#

Destroy action clients to the move_group node

create_all_service_clients()#

Create service clients to the move_group node

destroy_all_service_clients()#

Destroy service clients to the move_group node

custom_on_activate()#

Activate component and check the configured planner against move_group

custom_on_deactivate()#

Stop the scene refresh before the clients it uses are destroyed

main_action_callback(goal_handle)#

Callback for the MoveIt component main action server

Parameters:

goal_handle (MoveManipulator.Goal) – Incoming action goal

Returns:

Action result

Return type:

MoveManipulator.Result

open_gripper() → agents.ros.ActionReturnType#

Open the gripper

close_gripper() → agents.ros.ActionReturnType#

Close the gripper

set_gripper(position: float) → agents.ros.ActionReturnType#

Move the gripper to a given position

stop_motion() → agents.ros.ActionReturnType#

Cancel any motion in progress

get_named_targets() → agents.ros.ActionReturnType#

List the named targets available per planning group

add_collision_object(object_id: str, center: List[float], size: List[float], frame_id: str = '') → agents.ros.ActionReturnType#

Add a box-shaped collision object to the planning scene.

Parameters:
  • object_id – Scene-wide name; re-using one moves the object

  • center – Center of the box as [x, y, z] in meters

  • size – Full extents of the box as [x, y, z] in meters

  • frame_id – Frame the center is given in. Empty falls back to the configured pose_reference_frame, and an empty frame is read by move_group as its planning frame

Returns:

Whether it succeeded and what happened, for the caller and for tool use

remove_collision_object(object_id: str) → agents.ros.ActionReturnType#

Remove one collision object from the planning scene.

Parameters:

object_id – Id the object was added under

Returns:

Whether it succeeded and what happened, for the caller and for tool use

clear_collision_objects(detections_only: bool = False) → agents.ros.ActionReturnType#

Remove the collision objects this component put in the scene.

Only objects this component knows it added are touched, so obstacles placed by other tools stay where they are.

Parameters:

detections_only – Only remove detection-sourced objects, keeping manually added ones

Returns:

Whether it succeeded and what happened, for the caller and for tool use

list_collision_objects() → agents.ros.ActionReturnType#

List the collision objects in the planning scene.

The scene is read back from move_group, which is authoritative: it also shows objects placed there by other tools. When move_group does not answer, the objects this component itself added are listed.

Returns:

Success, with the object names for the caller and for tool use

clear_octomap() → agents.ros.ActionReturnType#

Clear the octomap accumulated in the planning scene.

Returns:

Whether it succeeded and what happened, for the caller and for tool use

attach_object(object_id: str, link_name: str = '', touch_links: Optional[List[str]] = None) → agents.ros.ActionReturnType#

Attach a scene object to a robot link, as on a grasp.

move_group removes the object from the world and carries it with the link; contact with the touch links stops counting as collision.

Parameters:
  • object_id – Name of an object already in the planning scene

  • link_name – Link the object is rigidly attached to. Empty uses the configured end effector link

  • touch_links – Links allowed to stay in contact with the object. Default resolves them from the config or the robot SRDF

Returns:

Whether it succeeded and what happened, for the caller and for tool use

detach_object(object_id: str, remove: bool = False) → agents.ros.ActionReturnType#

Detach an attached object, returning it to the world.

Parameters:
  • object_id – Name the object was attached under

  • remove – Also remove the object from the scene entirely. The default keeps it where it was released, which matches what physically happened

Returns:

Whether it succeeded and what happened, for the caller and for tool use

update_planning_scene() → agents.ros.ActionReturnType#

Update the planning scene from the latest received detections.

Calling this explicitly overrides the automatic freeze left by an interrupted pick or place. The freeze while an object is held stands.

Returns:

Whether it succeeded and what happened, for the caller and for tool use

custom_on_configure()#

Custom configurateion in case trigger is an event

init_variables()#

Partition trigger inputs out of the callbacks dict, at activation.

This runs AFTER a robot plugin adapted the callbacks, so the objects moved into trig_callbacks are the adapted ones. Idempotent across reactivations.

create_all_subscribers()#

Override to handle trigger topics and fixed inputs. Called by parent BaseComponent

activate_all_triggers() → None#

Activates component triggers by attaching execution step to callbacks

destroy_all_subscribers() → None#

Destroys all node subscribers