chore: publish rSkill OpenRAL/rskill-nav2-navigate-to-pose v0.1.0
Browse files- README.md +182 -0
- rskill.yaml +195 -0
README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
tags:
|
| 3 |
+
- OpenRAL
|
| 4 |
+
- rskill
|
| 5 |
+
- ros2
|
| 6 |
+
- nav2
|
| 7 |
+
license: apache-2.0
|
| 8 |
+
language:
|
| 9 |
+
- en
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# rskill-nav2-navigate-to-pose
|
| 13 |
+
|
| 14 |
+
> **OpenRAL rSkill** β wraps the upstream `nav2_msgs/action/NavigateToPose`
|
| 15 |
+
> action server as an OpenRAL rSkill so the Reasoner can dispatch
|
| 16 |
+
> mobile-base navigation through the same `ExecuteSkill` path used by
|
| 17 |
+
> VLA skills. **Result-only mode** β Nav2's behaviour tree publishes
|
| 18 |
+
> `/cmd_vel` directly to the base controller; no `Action` chunk flows
|
| 19 |
+
> through OpenRAL's safety supervisor.
|
| 20 |
+
|
| 21 |
+
This package uses `kind: ros_action` (see
|
| 22 |
+
[ADR-0024](../../docs/adr/0024-ros-wrapped-rskills.md)) with
|
| 23 |
+
`ros_integration.result_trajectory_field: null` to put the
|
| 24 |
+
[`ROSActionRskill`](../../python/rskill/src/openral_rskill/ros_action_rskill.py)
|
| 25 |
+
adapter into result-only mode: it sends the goal, awaits the action
|
| 26 |
+
result, and raises `ROSRskillGoalSatisfied` on success. Compare with
|
| 27 |
+
the sibling [`rskill-moveit-joints`](../rskill-moveit-joints/)
|
| 28 |
+
skill, which sets `result_trajectory_field` and replays a joint
|
| 29 |
+
trajectory one waypoint at a time.
|
| 30 |
+
|
| 31 |
+
## What this skill does
|
| 32 |
+
|
| 33 |
+
Navigates the mobile base to a fixed `geometry_msgs/PoseStamped` target
|
| 34 |
+
in the `map` frame via Nav2's `NavigateToPose` action. The default goal
|
| 35 |
+
points at the map origin; override `ros_integration.default_goal_json`
|
| 36 |
+
in a per-deployment copy for real targets.
|
| 37 |
+
|
| 38 |
+
| Field | Value |
|
| 39 |
+
| --- | --- |
|
| 40 |
+
| Actions | `navigate` |
|
| 41 |
+
| Objects | _none_ |
|
| 42 |
+
| Scenes | `indoor` |
|
| 43 |
+
| Embodiment | mobile-manipulator and similar mobile-base embodiments |
|
| 44 |
+
|
| 45 |
+
## How it works
|
| 46 |
+
|
| 47 |
+
`ROSActionRskill` is a thin `rSkillBase` shim around an `ActionClient`:
|
| 48 |
+
|
| 49 |
+
1. `_configure_impl` lazy-imports `nav2_msgs.action.NavigateToPose`,
|
| 50 |
+
opens an `ActionClient` on `/navigate_to_pose` from the
|
| 51 |
+
`RskillRunnerNode`-supplied node handle, and parses
|
| 52 |
+
`ros_integration.default_goal_json` once.
|
| 53 |
+
2. On the first `_step_impl(world_state)` call the adapter sends the
|
| 54 |
+
goal, polls the goal-accept + result futures while the host node's
|
| 55 |
+
main rclpy spin services callbacks, and β because
|
| 56 |
+
`result_trajectory_field is None` β raises
|
| 57 |
+
`ROSRskillGoalSatisfied` immediately on success. The runner catches
|
| 58 |
+
it specifically and closes the `ExecuteSkill` goal with
|
| 59 |
+
`success=True`.
|
| 60 |
+
|
| 61 |
+
### Observation β action contract (result-only mode)
|
| 62 |
+
|
| 63 |
+
| Direction | Key | Shape | Notes |
|
| 64 |
+
| --- | --- | --- | --- |
|
| 65 |
+
| in | `world_state.joint_state` | unused | Nav2 consumes its own sensor topics (laser, odom, camera) |
|
| 66 |
+
| out | _none via OpenRAL_ | β | Nav2's behaviour tree publishes `/cmd_vel` directly to the base controller |
|
| 67 |
+
|
| 68 |
+
**Safety implication.** No `ActionChunk` is published on
|
| 69 |
+
`/openral/candidate_action`, so the OpenRAL safety supervisor does NOT
|
| 70 |
+
see Nav2's velocity commands. Collision avoidance relies entirely on
|
| 71 |
+
Nav2's costmap + behaviour tree. The follow-up that brings velocity
|
| 72 |
+
streams under the supervisor's envelope is tracked in ADR-0024's
|
| 73 |
+
Β§Out-of-scope and depends on (a) a mobile-base HAL declaring
|
| 74 |
+
`body_twist` in `supported_control_modes` (none exist in-tree today),
|
| 75 |
+
and (b) a velocity / jerk envelope landing in the supervisor (it
|
| 76 |
+
currently checks per-joint position only).
|
| 77 |
+
|
| 78 |
+
## How it was trained / Upstream provenance
|
| 79 |
+
|
| 80 |
+
Nothing is trained β this rSkill wraps the upstream Nav2 stack.
|
| 81 |
+
|
| 82 |
+
| Field | Value |
|
| 83 |
+
| --- | --- |
|
| 84 |
+
| Upstream | [`nav2_msgs/action/NavigateToPose`](https://github.com/ros-navigation/navigation2/blob/main/nav2_msgs/action/NavigateToPose.action) (Apache-2.0) |
|
| 85 |
+
| Planner library | [Nav2](https://docs.nav2.org/) (Apache-2.0) |
|
| 86 |
+
| Costmap / behaviour tree | Nav2's own subsystems β see Nav2 docs |
|
| 87 |
+
| Wrapped artefact | rSkill manifest + README β no weights |
|
| 88 |
+
|
| 89 |
+
## Supported robots / embodiments
|
| 90 |
+
|
| 91 |
+
| Robot | Embodiment tag | Status | Notes |
|
| 92 |
+
| --- | --- | --- | --- |
|
| 93 |
+
| Panda Mobile | `panda_mobile` | experimental | no HAL accepting `body_twist` ships in-tree yet; resolution depends on the deployment wiring its own mobile-base HAL or running Nav2's controllers against a sim |
|
| 94 |
+
| Generic mobile-manipulator | `mobile_manipulator` | experimental | union tag β palette filter only |
|
| 95 |
+
|
| 96 |
+
A real mobile-base HAL (Turtlebot 4, Clearpath Jackal, etc.) is the
|
| 97 |
+
prerequisite for full end-to-end execution β tracked as a separate
|
| 98 |
+
issue.
|
| 99 |
+
|
| 100 |
+
## Sensors required / Observation contract
|
| 101 |
+
|
| 102 |
+
This skill consumes nothing through OpenRAL's sensor pipeline. Nav2's
|
| 103 |
+
own subscriptions handle:
|
| 104 |
+
|
| 105 |
+
| Source | Topic | Why Nav2 needs it |
|
| 106 |
+
| --- | --- | --- |
|
| 107 |
+
| Laser scan | `/scan` (or per-deployment remap) | Costmap obstacle layer |
|
| 108 |
+
| Odometry | `/odom` | Localisation + behaviour-tree feedback |
|
| 109 |
+
| TF | `/tf`, `/tf_static` | Resolve goal pose in the `map` frame |
|
| 110 |
+
| Map | `/map` (or AMCL initial pose) | Global planner |
|
| 111 |
+
|
| 112 |
+
If your deployment uses a non-default topic remap, surface it on the
|
| 113 |
+
Nav2 launch β the wrapped action's contract is intact.
|
| 114 |
+
|
| 115 |
+
## Manifest summary
|
| 116 |
+
|
| 117 |
+
| Field | Value |
|
| 118 |
+
| --- | --- |
|
| 119 |
+
| `name` | `OpenRAL/rskill-nav2-navigate-to-pose` |
|
| 120 |
+
| `version` | `0.1.0` |
|
| 121 |
+
| `license` | `apache-2.0` |
|
| 122 |
+
| `kind` | `ros_action` |
|
| 123 |
+
| `role` | `s1` |
|
| 124 |
+
| `actions` | `[navigate]` |
|
| 125 |
+
| `chunk_size` | `1` (schema-enforced for `kind: ros_action`) |
|
| 126 |
+
| `latency_budget.per_chunk_ms` | `60000` (navigation is long-horizon; the adapter waits Γ5 of this on the action result) |
|
| 127 |
+
| `ros_integration.package` | `nav2_msgs` |
|
| 128 |
+
| `ros_integration.interface_type` | `NavigateToPose` |
|
| 129 |
+
| `ros_integration.interface_name` | `/navigate_to_pose` |
|
| 130 |
+
| `ros_integration.result_trajectory_field` | _omitted β result-only mode_ |
|
| 131 |
+
| `commercial_use_allowed` | `true` (apache-2.0) |
|
| 132 |
+
|
| 133 |
+
Full schema:
|
| 134 |
+
[`openral_core.schemas.RSkillManifest`](../../python/core/src/openral_core/schemas.py).
|
| 135 |
+
|
| 136 |
+
## Quick start
|
| 137 |
+
|
| 138 |
+
```python
|
| 139 |
+
from openral_rskill.loader import rSkill
|
| 140 |
+
pkg = rSkill.from_yaml("rskills/rskill-nav2-navigate-to-pose/rskill.yaml")
|
| 141 |
+
print(pkg.manifest.name, pkg.manifest.kind, pkg.manifest.ros_integration.interface_name)
|
| 142 |
+
```
|
| 143 |
+
|
| 144 |
+
End-to-end, with a real Nav2 launch up (e.g. against a Gazebo /
|
| 145 |
+
Turtlebot4 sim):
|
| 146 |
+
|
| 147 |
+
```bash
|
| 148 |
+
# 1. Bring up Nav2 for your mobile-base sim or robot
|
| 149 |
+
ros2 launch nav2_bringup tb4_simulation_launch.py
|
| 150 |
+
|
| 151 |
+
# 2. Bring up the OpenRAL runner against that embodiment
|
| 152 |
+
ros2 launch openral_rskill_ros skill_runner.launch.py robot:=panda_mobile
|
| 153 |
+
|
| 154 |
+
# 3. From the Reasoner (or by hand), dispatch the goal:
|
| 155 |
+
ros2 action send_goal /openral/execute_skill openral_msgs/action/ExecuteSkill \
|
| 156 |
+
"{rskill_id: 'OpenRAL/rskill-nav2-navigate-to-pose', deadline_s: 120.0, prompt: 'go to map origin'}"
|
| 157 |
+
```
|
| 158 |
+
|
| 159 |
+
## Limitations / Roadmap
|
| 160 |
+
|
| 161 |
+
- **Velocity stream bypasses the OpenRAL safety supervisor.** Nav2
|
| 162 |
+
publishes `/cmd_vel` directly. See ADR-0024 Β§Out-of-scope.
|
| 163 |
+
- **Goal hard-coded in the manifest.** v1 ships one goal per
|
| 164 |
+
manifest; structured-prompt support is the next ADR.
|
| 165 |
+
- **No mobile-base HAL in-tree.** Until one lands, the skill resolves
|
| 166 |
+
only inside deployments that ship their own mobile-base wiring.
|
| 167 |
+
|
| 168 |
+
## License
|
| 169 |
+
|
| 170 |
+
The rSkill package itself (this manifest + README) is **Apache-2.0**.
|
| 171 |
+
The wrapped Nav2 code (`nav2_msgs` IDL, `navigation2` planners) is
|
| 172 |
+
**Apache-2.0** and lives outside this repository β installed via
|
| 173 |
+
`ros-${ROS_DISTRO}-nav2-bringup`. Per
|
| 174 |
+
[ADR-0012](../../docs/adr/0012-open-core-licensing.md) both postures
|
| 175 |
+
are commercial-use-permissive.
|
| 176 |
+
|
| 177 |
+
## See also
|
| 178 |
+
|
| 179 |
+
- [ADR-0024 β ROS-wrapped rSkills](../../docs/adr/0024-ros-wrapped-rskills.md)
|
| 180 |
+
- [`openral_rskill.ros_action_rskill`](../../python/rskill/src/openral_rskill/ros_action_rskill.py) β adapter source
|
| 181 |
+
- [`rskills/rskill-moveit-joints/`](../rskill-moveit-joints/) β sibling MoveIt wrapper (trajectory mode)
|
| 182 |
+
- [CLAUDE.md Β§3 β Architecture Discipline](../../CLAUDE.md)
|
rskill.yaml
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# rSkill manifest β Nav2 NavigateToPose (kind: ros_action, result-only)
|
| 2 |
+
#
|
| 3 |
+
# Wraps the upstream `nav2_msgs/action/NavigateToPose` action server as
|
| 4 |
+
# an OpenRAL rSkill. See `docs/adr/0024-ros-wrapped-rskills.md`.
|
| 5 |
+
#
|
| 6 |
+
# RESULT-ONLY MODE
|
| 7 |
+
# ----------------
|
| 8 |
+
# `ros_integration.result_trajectory_field` is omitted, which puts the
|
| 9 |
+
# adapter into result-only mode: it sends the goal, awaits the action
|
| 10 |
+
# result, and raises `ROSRskillGoalSatisfied` on success. NO `Action`
|
| 11 |
+
# chunk is emitted to `/openral/candidate_action`. Nav2's own behaviour
|
| 12 |
+
# tree publishes `cmd_vel` directly to the base controller, BYPASSING
|
| 13 |
+
# the OpenRAL safety supervisor for those velocity commands. Collision
|
| 14 |
+
# avoidance relies entirely on Nav2's costmap. The Out-of-scope section
|
| 15 |
+
# of ADR-0024 tracks the follow-up that brings velocity-stream safety
|
| 16 |
+
# under the supervisor's check (no in-tree HAL exposes `body_twist` in
|
| 17 |
+
# `supported_control_modes` today, so this is also blocked on a
|
| 18 |
+
# mobile-base HAL landing β issue tracked separately).
|
| 19 |
+
#
|
| 20 |
+
# ADR-0026 β per-dispatch structured parameters. The LLM tool palette
|
| 21 |
+
# surfaces this schema to the provider; the reasoner attaches the
|
| 22 |
+
# generated payload as ``goal_params_json`` on the ExecuteSkill goal;
|
| 23 |
+
# the wrapped-action adapter deep-merges it over the
|
| 24 |
+
# ``default_goal_json`` below at configure-time. Omit fields you want
|
| 25 |
+
# from the manifest default.
|
| 26 |
+
|
| 27 |
+
schema_version: "0.1"
|
| 28 |
+
name: "OpenRAL/rskill-nav2-navigate-to-pose"
|
| 29 |
+
version: "0.1.0"
|
| 30 |
+
license: "apache-2.0"
|
| 31 |
+
role: "s1"
|
| 32 |
+
kind: "ros_action"
|
| 33 |
+
|
| 34 |
+
# `mobile_base` is the canonical CLASS tag for any robot with a planar
|
| 35 |
+
# base + ``body_twist`` actuator (defined in ``openral_core.schemas``
|
| 36 |
+
# alongside the robot-specific tags). A robot must (a) declare this tag
|
| 37 |
+
# in its ``robots/<id>/robot.yaml`` and (b) be reachable by a running
|
| 38 |
+
# Nav2 stack on this deployment for the skill to actually resolve.
|
| 39 |
+
# Robot-specific tags (``panda_mobile`` etc.) intentionally do NOT
|
| 40 |
+
# appear here β Nav2's behaviour is base-agnostic, so the manifest
|
| 41 |
+
# stays generic and any mobile_base robot can target it.
|
| 42 |
+
embodiment_tags:
|
| 43 |
+
- "mobile_base"
|
| 44 |
+
|
| 45 |
+
# Body twist is what Nav2's behaviour-tree controllers ultimately
|
| 46 |
+
# publish on `/cmd_vel`. Declaring it here is the honest description of
|
| 47 |
+
# what the wrapped server commands; the OpenRAL ActionChunk path is NOT
|
| 48 |
+
# used (see result-only mode above).
|
| 49 |
+
actuators_required:
|
| 50 |
+
- kind: "body_twist"
|
| 51 |
+
control_mode_semantics:
|
| 52 |
+
mode: "absolute"
|
| 53 |
+
|
| 54 |
+
# `chunk_size: 1` is REQUIRED for kind: ros_action even in result-only
|
| 55 |
+
# mode (the schema validator enforces it uniformly across both modes).
|
| 56 |
+
chunk_size: 1
|
| 57 |
+
|
| 58 |
+
# Navigation is long-horizon β a full run can take 30+ seconds. The
|
| 59 |
+
# adapter waits Γ5 of this as the action-result deadline, so allow
|
| 60 |
+
# enough headroom (60 s here β 300 s wait ceiling).
|
| 61 |
+
latency_budget:
|
| 62 |
+
per_chunk_ms: 60000.0
|
| 63 |
+
|
| 64 |
+
# ADR-0022 β surfaced to the Reasoner LLM tool palette.
|
| 65 |
+
description: >
|
| 66 |
+
Navigate the mobile base to a target pose via Nav2's NavigateToPose.
|
| 67 |
+
Supports BOTH absolute and relative goals via pose.header.frame_id:
|
| 68 |
+
"map" = absolute world coordinates (drive to (3.5, 2.1)); "base_link"
|
| 69 |
+
= relative to current pose, used for turns / forward / back-up
|
| 70 |
+
(Nav2 transforms via tf2 on goal accept β the LLM does NOT need to
|
| 71 |
+
compose quaternions against the live pose). Result-only mode: Nav2
|
| 72 |
+
publishes cmd_vel directly; collision avoidance relies on its costmap.
|
| 73 |
+
actions:
|
| 74 |
+
- "navigate"
|
| 75 |
+
objects: []
|
| 76 |
+
scenes:
|
| 77 |
+
- "indoor"
|
| 78 |
+
|
| 79 |
+
# Provenance β required by the rSkill doc validator's publish gate.
|
| 80 |
+
# See sibling moveit-plan-arm manifest for the rationale on using
|
| 81 |
+
# `paper_url` rather than `source_repo` for ROS-wrapped rSkills.
|
| 82 |
+
paper_url: "https://docs.nav2.org/"
|
| 83 |
+
|
| 84 |
+
ros_integration:
|
| 85 |
+
package: "nav2_msgs"
|
| 86 |
+
interface_type: "NavigateToPose"
|
| 87 |
+
interface_name: "/navigate_to_pose"
|
| 88 |
+
# OMITTED β result-only mode (the adapter awaits the result and
|
| 89 |
+
# raises ROSRskillGoalSatisfied without emitting any Action chunk).
|
| 90 |
+
result_trajectory_field: null
|
| 91 |
+
# Default = "stay where you are" (identity offset in base_link).
|
| 92 |
+
# Picked so a misconfigured dispatch is a no-op (Nav2 reports
|
| 93 |
+
# "Reached the goal" without moving) rather than a wild drive to
|
| 94 |
+
# the map origin. The reasoner MUST override at least one of
|
| 95 |
+
# ``pose.position.{x,y}`` or ``pose.orientation.{z,w}`` to actually
|
| 96 |
+
# command motion.
|
| 97 |
+
default_goal_json: |
|
| 98 |
+
{
|
| 99 |
+
"pose": {
|
| 100 |
+
"header": {
|
| 101 |
+
"frame_id": "base_link"
|
| 102 |
+
},
|
| 103 |
+
"pose": {
|
| 104 |
+
"position": {"x": 0.0, "y": 0.0, "z": 0.0},
|
| 105 |
+
"orientation": {"x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0}
|
| 106 |
+
}
|
| 107 |
+
},
|
| 108 |
+
"behavior_tree": ""
|
| 109 |
+
}
|
| 110 |
+
ros_dependencies:
|
| 111 |
+
- "ros-${ROS_DISTRO}-nav2-bringup"
|
| 112 |
+
- "ros-${ROS_DISTRO}-nav2-msgs"
|
| 113 |
+
|
| 114 |
+
# ADR-0026 β per-skill JSON Schema surfaced to the Reasoner LLM tool
|
| 115 |
+
# palette. The LLM produces a JSON object matching this schema; the
|
| 116 |
+
# adapter deep-merges over ``default_goal_json`` at configure-time.
|
| 117 |
+
#
|
| 118 |
+
# The schema unifies absolute and relative goals: pick ``frame_id``
|
| 119 |
+
# to choose, fill in position + orientation as offsets in that frame.
|
| 120 |
+
# Nav2's bt_navigator transforms the goal to the planning frame on
|
| 121 |
+
# accept via tf2, so the LLM does not need to compose quaternions
|
| 122 |
+
# against the live robot pose β declare the offset in ``base_link``
|
| 123 |
+
# and Nav2 does the math.
|
| 124 |
+
goal_params_schema:
|
| 125 |
+
type: object
|
| 126 |
+
description: >
|
| 127 |
+
Target pose for Nav2's NavigateToPose action. Position +
|
| 128 |
+
orientation are interpreted in ``pose.header.frame_id`` (Nav2
|
| 129 |
+
transforms to its planning frame on accept).
|
| 130 |
+
properties:
|
| 131 |
+
pose:
|
| 132 |
+
type: object
|
| 133 |
+
properties:
|
| 134 |
+
header:
|
| 135 |
+
type: object
|
| 136 |
+
properties:
|
| 137 |
+
frame_id:
|
| 138 |
+
type: string
|
| 139 |
+
enum: ["map", "odom", "base_link"]
|
| 140 |
+
description: >
|
| 141 |
+
Frame the position + orientation are expressed in.
|
| 142 |
+
``map`` = absolute world goal (use when you know the
|
| 143 |
+
world coordinate, e.g. "drive to (3.5, 2.1)").
|
| 144 |
+
``base_link`` = relative to current pose (use for
|
| 145 |
+
turn / forward / back-up commands β position is the
|
| 146 |
+
offset in metres ahead/left/up of the robot, and
|
| 147 |
+
orientation is the rotation from current heading).
|
| 148 |
+
``odom`` = relative-ish (drifts over time, prefer
|
| 149 |
+
``base_link``).
|
| 150 |
+
required: ["frame_id"]
|
| 151 |
+
pose:
|
| 152 |
+
type: object
|
| 153 |
+
properties:
|
| 154 |
+
position:
|
| 155 |
+
type: object
|
| 156 |
+
properties:
|
| 157 |
+
x:
|
| 158 |
+
type: number
|
| 159 |
+
description: >
|
| 160 |
+
Target x (m). In ``base_link`` frame this is
|
| 161 |
+
forward distance (positive = ahead, negative =
|
| 162 |
+
backward). In ``map`` frame this is the absolute
|
| 163 |
+
world x coordinate.
|
| 164 |
+
y:
|
| 165 |
+
type: number
|
| 166 |
+
description: >
|
| 167 |
+
Target y (m). In ``base_link`` frame this is
|
| 168 |
+
leftward distance (positive = left). In ``map``
|
| 169 |
+
frame this is the absolute world y coordinate.
|
| 170 |
+
z:
|
| 171 |
+
type: number
|
| 172 |
+
description: "Target z (m); ground robots use 0."
|
| 173 |
+
required: ["x", "y"]
|
| 174 |
+
orientation:
|
| 175 |
+
type: object
|
| 176 |
+
description: >
|
| 177 |
+
Target orientation as a quaternion. For ground robots
|
| 178 |
+
the only non-zero components are ``z = sin(yaw/2)``
|
| 179 |
+
and ``w = cos(yaw/2)`` (yaw rotation around vertical
|
| 180 |
+
axis). In ``base_link`` frame the quaternion is the
|
| 181 |
+
rotation FROM current heading; in ``map`` frame it
|
| 182 |
+
is the absolute world heading.
|
| 183 |
+
Common values for ``base_link`` turns:
|
| 184 |
+
- identity (no rotation): z=0, w=1
|
| 185 |
+
- +90Β° (counter-clockwise): z=0.7071, w=0.7071
|
| 186 |
+
- -90Β° (clockwise): z=-0.7071, w=0.7071
|
| 187 |
+
- 180Β°: z=1.0, w=0
|
| 188 |
+
properties:
|
| 189 |
+
x: { type: number, description: "Quaternion x component." }
|
| 190 |
+
y: { type: number, description: "Quaternion y component." }
|
| 191 |
+
z: { type: number, description: "Quaternion z component (sin(yaw/2) for a pure yaw rotation)." }
|
| 192 |
+
w: { type: number, description: "Quaternion w component (cos(yaw/2) for a pure yaw rotation)." }
|
| 193 |
+
required: ["position", "orientation"]
|
| 194 |
+
required: ["pose"]
|
| 195 |
+
required: ["pose"]
|