# rSkill manifest — Nav2 NavigateToPose (kind: ros_action, result-only) # # Wraps the upstream `nav2_msgs/action/NavigateToPose` action server as # an OpenRAL rSkill. See `docs/adr/0024-ros-wrapped-rskills.md`. # # RESULT-ONLY MODE # ---------------- # `ros_integration.result_trajectory_field` is omitted, which puts the # adapter into result-only mode: it sends the goal, awaits the action # result, and raises `ROSRskillGoalSatisfied` on success. NO `Action` # chunk is emitted to `/openral/candidate_action`. Nav2's own behaviour # tree publishes `cmd_vel` directly to the base controller, BYPASSING # the OpenRAL safety supervisor for those velocity commands. Collision # avoidance relies entirely on Nav2's costmap. The Out-of-scope section # of ADR-0024 tracks the follow-up that brings velocity-stream safety # under the supervisor's check (no in-tree HAL exposes `body_twist` in # `supported_control_modes` today, so this is also blocked on a # mobile-base HAL landing — issue tracked separately). # # ADR-0026 — per-dispatch structured parameters. The LLM tool palette # surfaces this schema to the provider; the reasoner attaches the # generated payload as ``goal_params_json`` on the ExecuteSkill goal; # the wrapped-action adapter deep-merges it over the # ``default_goal_json`` below at configure-time. Omit fields you want # from the manifest default. schema_version: "0.1" name: "OpenRAL/rskill-nav2-navigate-to-pose" version: "0.1.0" license: "apache-2.0" role: "s1" kind: "ros_action" # `mobile_base` is the canonical CLASS tag for any robot with a planar # base + ``body_twist`` actuator (defined in ``openral_core.schemas`` # alongside the robot-specific tags). A robot must (a) declare this tag # in its ``robots//robot.yaml`` and (b) be reachable by a running # Nav2 stack on this deployment for the skill to actually resolve. # Robot-specific tags (``panda_mobile`` etc.) intentionally do NOT # appear here — Nav2's behaviour is base-agnostic, so the manifest # stays generic and any mobile_base robot can target it. embodiment_tags: - "mobile_base" # Body twist is what Nav2's behaviour-tree controllers ultimately # publish on `/cmd_vel`. Declaring it here is the honest description of # what the wrapped server commands; the OpenRAL ActionChunk path is NOT # used (see result-only mode above). actuators_required: - kind: "body_twist" control_mode_semantics: mode: "absolute" # `chunk_size: 1` is REQUIRED for kind: ros_action even in result-only # mode (the schema validator enforces it uniformly across both modes). chunk_size: 1 # Navigation is long-horizon — a full run can take 30+ seconds. The # adapter waits ×5 of this as the action-result deadline, so allow # enough headroom (60 s here → 300 s wait ceiling). latency_budget: per_chunk_ms: 60000.0 # ADR-0022 — surfaced to the Reasoner LLM tool palette. description: > Navigate the mobile base to a target pose via Nav2's NavigateToPose. Supports BOTH absolute and relative goals via pose.header.frame_id: "map" = absolute world coordinates (drive to (3.5, 2.1)); "base_link" = relative to current pose, used for turns / forward / back-up (Nav2 transforms via tf2 on goal accept — the LLM does NOT need to compose quaternions against the live pose). Result-only mode: Nav2 publishes cmd_vel directly; collision avoidance relies on its costmap. actions: - "navigate" objects: [] scenes: - "indoor" # Provenance — required by the rSkill doc validator's publish gate. # See sibling moveit-plan-arm manifest for the rationale on using # `paper_url` rather than `source_repo` for ROS-wrapped rSkills. paper_url: "https://docs.nav2.org/" ros_integration: package: "nav2_msgs" interface_type: "NavigateToPose" interface_name: "/navigate_to_pose" # OMITTED → result-only mode (the adapter awaits the result and # raises ROSRskillGoalSatisfied without emitting any Action chunk). result_trajectory_field: null # Default = "stay where you are" (identity offset in base_link). # Picked so a misconfigured dispatch is a no-op (Nav2 reports # "Reached the goal" without moving) rather than a wild drive to # the map origin. The reasoner MUST override at least one of # ``pose.position.{x,y}`` or ``pose.orientation.{z,w}`` to actually # command motion. default_goal_json: | { "pose": { "header": { "frame_id": "base_link" }, "pose": { "position": {"x": 0.0, "y": 0.0, "z": 0.0}, "orientation": {"x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0} } }, "behavior_tree": "" } ros_dependencies: - "ros-${ROS_DISTRO}-nav2-bringup" - "ros-${ROS_DISTRO}-nav2-msgs" # ADR-0026 — per-skill JSON Schema surfaced to the Reasoner LLM tool # palette. The LLM produces a JSON object matching this schema; the # adapter deep-merges over ``default_goal_json`` at configure-time. # # The schema unifies absolute and relative goals: pick ``frame_id`` # to choose, fill in position + orientation as offsets in that frame. # Nav2's bt_navigator transforms the goal to the planning frame on # accept via tf2, so the LLM does not need to compose quaternions # against the live robot pose — declare the offset in ``base_link`` # and Nav2 does the math. goal_params_schema: type: object description: > Target pose for Nav2's NavigateToPose action. Position + orientation are interpreted in ``pose.header.frame_id`` (Nav2 transforms to its planning frame on accept). properties: pose: type: object properties: header: type: object properties: frame_id: type: string enum: ["map", "odom", "base_link"] description: > Frame the position + orientation are expressed in. ``map`` = absolute world goal (use when you know the world coordinate, e.g. "drive to (3.5, 2.1)"). ``base_link`` = relative to current pose (use for turn / forward / back-up commands — position is the offset in metres ahead/left/up of the robot, and orientation is the rotation from current heading). ``odom`` = relative-ish (drifts over time, prefer ``base_link``). required: ["frame_id"] pose: type: object properties: position: type: object properties: x: type: number description: > Target x (m). In ``base_link`` frame this is forward distance (positive = ahead, negative = backward). In ``map`` frame this is the absolute world x coordinate. y: type: number description: > Target y (m). In ``base_link`` frame this is leftward distance (positive = left). In ``map`` frame this is the absolute world y coordinate. z: type: number description: "Target z (m); ground robots use 0." required: ["x", "y"] orientation: type: object description: > Target orientation as a quaternion. For ground robots the only non-zero components are ``z = sin(yaw/2)`` and ``w = cos(yaw/2)`` (yaw rotation around vertical axis). In ``base_link`` frame the quaternion is the rotation FROM current heading; in ``map`` frame it is the absolute world heading. Common values for ``base_link`` turns: - identity (no rotation): z=0, w=1 - +90° (counter-clockwise): z=0.7071, w=0.7071 - -90° (clockwise): z=-0.7071, w=0.7071 - 180°: z=1.0, w=0 properties: x: { type: number, description: "Quaternion x component." } y: { type: number, description: "Quaternion y component." } z: { type: number, description: "Quaternion z component (sin(yaw/2) for a pure yaw rotation)." } w: { type: number, description: "Quaternion w component (cos(yaw/2) for a pure yaw rotation)." } required: ["position", "orientation"] required: ["pose"] required: ["pose"]