File size: 8,489 Bytes
b520531 18faa4f b520531 18faa4f b520531 18faa4f b520531 fa9f6ae b520531 18faa4f b520531 18faa4f b520531 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | # rSkill manifest — Nav2 NavigateToPose (kind: ros_action, result-only)
#
# Wraps the upstream `nav2_msgs/action/NavigateToPose` action server as
# an OpenRAL rSkill.
#
# 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. Bringing velocity-stream
# safety under the supervisor's check is an explicit out-of-scope
# follow-up for the ROS-wrapped rSkills design (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).
#
# 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-mobile_base-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/<id>/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
# 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"
# 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"]
|