Skip to content

Commit

Permalink
Update global planner ICD (#107)
Browse files Browse the repository at this point in the history
fix typo in doc

Add screenshot of vscode debugger

Add diagram for docker containers

Remove global robot name from rviz
  • Loading branch information
andrewjong authored Oct 22, 2024
1 parent 15646e2 commit 7aa27c0
Show file tree
Hide file tree
Showing 7 changed files with 1,018 additions and 109 deletions.
40 changes: 39 additions & 1 deletion docs/development/docker_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,29 @@ This lets them communicate with ROS2 on the same network.

Each robot has its own ROS_DOMAIN_ID.

## Pull Images
To use the AirLab docker registry:
```bash
cd AirStack/docker/
docker login airlab-storage.andrew.cmu.edu:5001
## <Enter your andrew id (without @andrew.cmu.edu)>
## <Enter your andrew password>

## Pull the images in the docker compose file
docker compose pull
```

Catelog: [AirLab Registry Images](https://airlab-storage.andrew.cmu.edu:5001/v2/_catalog).

Available image tags:
[airstack-dev](https://airlab-storage.andrew.cmu.edu:5001/v2/shared/airstack-dev/tags/list),
[isaac-sim_ros-humble](https://airlab-storage.andrew.cmu.edu:5001/v2/shared/isaac-sim_ros-humble/tags/list)

## Build Images
```bash
docker compose build
```

## Start and Stop
Start
```bash
Expand Down Expand Up @@ -54,6 +77,20 @@ The ssh password is `airstack`.

## Container Details

```mermaid
graph TD
A(Isaac Sim) <-- Sensors and Actuation --> B
A <-- Sensors and Actuation --> C
B(Robot 1) <-- Global Info --> D(Ground Control Station)
C(Robot 2) <-- Global Info --> D
style A fill:#76B900,stroke:#333,stroke-width:2px
style B fill:#fbb,stroke:#333,stroke-width:2px
style C fill:#fbb,stroke:#333,stroke-width:2px
style D fill:#fbf,stroke:#333,stroke-width:2px
```


### Isaac Sim
Start a bash shell in the Isaac Sim container:
Expand All @@ -79,6 +116,7 @@ docker exec -it docker-robot-1 bash
# in robot docker
cws # cleans workspace
bws # builds workspace
bws --packages-select [your_packages] # builds only desired packages
sws # sources workspace
ros2 launch robot_bringup robot.launch.xml # top-level launch
```
Expand All @@ -97,4 +135,4 @@ docker exec -it ground-control-station bash

The commands are currently the same.

`ROS_DOMAIN_ID` is set to 0.
On the GCS `ROS_DOMAIN_ID` is set to 0.
Binary file added docs/development/vscode/debugger.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion docs/development/vscode/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ Launch tasks are defined in `.vscode/launch.json`.

![launch](launch.png)

You can now set breakpoints and debug as usual in VSCode.
You can now set breakpoints, view variables, step-through code, and debug [as usual in VSCode](https://code.visualstudio.com/docs/editor/debugging).

![debugger](debugger.png)


!!! warning "Warning about file permissions"
Expand Down
27 changes: 17 additions & 10 deletions docs/robot/autonomy/0_interface/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,49 @@ Launch files are under `src/robot/autonomy/0_interface/interface_bringup/launch`

The main launch command is `ros2 launch interface_bringup interface.launch.xml`.


## RobotInterface

Package `robot_interface` is a ROS2 node that interfaces with the robot's hardware.
The `RobotInterface` _gets robot state_ and forwards it to the autonomy stack,
The `RobotInterface` _gets robot state_ and forwards it to the autonomy stack,
and also _translates control commands_ from the autonomy stack into the command for the underlying hardware.
Note the base class is unimplemented.
Specific implementations should extend `class RobotInterface` in `robot_interface.hpp`, for example `class MAVROSInterface`.

### State

The `RobotInterface` class broadcasts the robot's pose as a TF2 transform.
It also publishes the robot's odometry as a `nav_msgs/Odometry` message to `$(arg robot_name)/0_interface/robot_0_interface/odometry`.
It also publishes the robot's odometry as a `nav_msgs/Odometry` message to `$(env ROBOT_NAME)/0_interface/robot_0_interface/odometry`.

### Commands

The commands are variations of the two main command modes: Attitude control and Position control.
These are reflected in [MAVLink](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_LOCAL_NED) and supported by both PX4 and [Ardupilot](https://ardupilot.org/dev/docs/copter-commands-in-guided-mode.html#movement-commands).

The Robot0_interface node subscribes to:
The RobotInterface node subscribes to:

- `/$(arg robot_name)/interface/cmd_attitude_thrust` of type `mav_msgs/AttitudeThrust.msg`
- `/$(arg robot_name)/interface/cmd_rate_thrust` of type `mav_msgs/RateThrust.msg`
- `/$(arg robot_name)/interface/cmd_roll_pitch_yawrate_thrust` of type `mav_msgs/RollPitchYawrateThrust.msg`
- `/$(arg robot_name)/interface/cmd_torque_thrust` of type `mav_msgs/TorqueThrust.msg`
- `/$(arg robot_name)/interface/cmd_velocity` of type `geometry_msgs/TwistStamped.msg`
- `/$(arg robot_name)/interface/cmd_position` of type `geometry_msgs/PoseStamped.msg`
- `/$(env ROBOT_NAME)/interface/cmd_attitude_thrust` of type `mav_msgs/AttitudeThrust.msg`
- `/$(env ROBOT_NAME)/interface/cmd_rate_thrust` of type `mav_msgs/RateThrust.msg`
- `/$(env ROBOT_NAME)/interface/cmd_roll_pitch_yawrate_thrust` of type `mav_msgs/RollPitchYawrateThrust.msg`
- `/$(env ROBOT_NAME)/interface/cmd_torque_thrust` of type `mav_msgs/TorqueThrust.msg`
- `/$(env ROBOT_NAME)/interface/cmd_velocity` of type `geometry_msgs/TwistStamped.msg`
- `/$(env ROBOT_NAME)/interface/cmd_position` of type `geometry_msgs/PoseStamped.msg`

All messages are in the robot's body frame, except `velocity` and `position` which use the frame specified by the message header.

## MAVROSInterface

The available implementation in AirStack is called `MAVROSInterface` implemented in `mavros_interface.cpp`. It simply forwards the control commands to the Ascent flight controller (based on Ardupilot) using MAVROS.

## Custom Robot Interface

If you're using a different robot control unit with its own custom API, then you need to create an associated RobotInterface. Implementations should do the following:

### Broadcast State

Implementations of `RobotInterface` should obtain the robot's pose and broadcast it as a TF2 transform.

Should look something like:

```c++
// callback function triggered by some loop
void your_callback_function(){
Expand All @@ -68,9 +73,11 @@ void your_callback_function(){
// ...
}
```

==TODO: our code doesn't currently do it like this, it instead uses an external odometry_conversion node.==

### Override Command Handling

Should override all `virtual` functions in `robot_interface.hpp`:

- `cmd_attitude_thrust_callback`
Expand Down
54 changes: 20 additions & 34 deletions docs/robot/autonomy/4_global/planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,39 @@ Feel free to implement your own through the following interfaces.

Global planners are meant to be modules that can be swapped out easily.
They can be thought of as different high level behaviors for the robot to follow.
The Behavior Executive may run multiple global planners in parallel and choose the best plan for the current situation.
Consider that multiple global planners may be run in parallel, for example by some ensemble planner node that chooses the best plan for the current situation.

As such, the global planner should be implemented as a ROS2 action server that can be queried for a plan.
The Behavior Executive will then publish the best plan to `/$(arg robot_name)/global/trajectory` for the local planner to follow.
As such, the global planner should be implemented as a ROS2 node that accepts runtime mission parameters in a custom `PlanRequest.msg` and
publishes a plan to its local `~/global_plan` topic.

The best global plan should then be forwarded or remapped to `/$(env ROBOT_NAME)/global_plan` for the local planner to follow.

``` mermaid
sequenceDiagram
autonumber
Behavior Executive->>Global Planner: GetPlan.action: goal
Some Node->>Global Planner: ~/plan_request (your_planner/PlanRequest.msg)
loop Planning
Global Planner->>Behavior Executive: GetPlan.action: feedback
Global Planner-->>Some Node: heartbeat feedback
end
Global Planner-->>Behavior Executive: GetPlan.action: result (nav_msgs/Path)
Behavior Executive-->>Local Planner: /$ROBOT_NAME/global/trajectory (nav_msgs/Path)
Global Planner->>Some Node: ~/global_plan (nav_msgs/Path.msg)
Some Node->>Local Planner: /$ROBOT_NAME/global_plan (nav_msgs/Path.msg)
```

### Actions Interface

Global Planner implementations should define a custom **GetPlan** action server and associated `GetPlan.action` message.
The action message may be defined with whatever input parameters necessary for the planner to generate a plan.
Your `GetPlan.action` _must_ return a `nav_msgs/Path` message.
### Subscribe: Plan Request
Your custom `PlanRequest.msg` defines the parameters that your global planner needs to generate a plan.
It will be sent on the `~/plan_request` topic.

An example `GetPlan.action` message is shown below.
Some common parameters may be the following:
```
# Define a goal
# PlanRequest.msg
std_msgs/Duration timeout # maximum time to spend planning
geometry_msgs/Polygon bounds # boundary that the plan must stay within
---
# Define the result that will be published after the action execution ends.
{==nav_msgs/Path trajectory # REQUIRED FIELD==}
---
# Define a feedback message that will be published during action execution.
float32 percent_complete
```


#### Goal
The goal defines the parameters that the global planner needs to generate a plan. All fields are optional.


#### Result
The global planner must have a return field `trajectory` of message type `nav_msgs/Path`.
`trajectory` defines high level waypoints to reach by a given time.
### Publish: Global Plan
The global planner must publish a message of type `nav_msgs/Path` to `~/global_plan`.
The message defines high level waypoints to reach by a given time.

The `nav_msgs/Path` message type contains a `header` field and `poses` field.

Expand All @@ -81,14 +71,10 @@ nav_msgs/Path.msg
- string frame_id: the coordinate frame of the waypoint
- geometry_msgs/Pose pose: the position and orientation of the waypoint
```
#### Feedback
All other fields are optional.


More info about ROS2 actions may be found in the official [tutorial](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Actions/Understanding-ROS2-Actions.html) and [design philosophy](https://design.ros2.org/articles/actions.html) documents.

### Publish: Heartbeat
For long-running global planners, it's recommended to publish a heartbeat message to `~/heartbeat`. This way the calling node can know that the global planner is still running and hasn't crashed.

### Subscribers
### Additional Subscribers
In general, the global planner needs to access components of the world model such as the map and drone state.

The most common map is Occupancy Grids that is published by {==TODO==} node.
Expand Down
Loading

0 comments on commit 7aa27c0

Please sign in to comment.