Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/getting-started/first-simulation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# First simulation

Bring up the X500 with the full ROS stack (Gazebo server, ros_gz bridge,
robot_state_publisher and the Gazebo GUI):

```bash
ros2 launch x500_gazebo sim.launch.xml
```

Gazebo opens with the X500 resting on its landing gear: the airframe, its
four 1345 propellers, the 4S battery and the GPS mast. That is the default
configuration; no configuration was involved. The model carries no control
layer, so the rotors idle until an autopilot publishes on the motor bus
([Actuators](../vehicles/x500/actuators.md)).

In a second terminal (also sourced), the flight sensors publish right away:

```bash
ros2 topic echo /x500/imu --once
ros2 topic echo /x500/gps/fix --once
```

Next: [change what is fitted](../vehicles/x500/configuration.md). The
[Running page](../vehicles/x500/running.md) covers worlds, custom configs
and RViz.
51 changes: 6 additions & 45 deletions docs/getting-started/index.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,11 @@
# Getting started

## Requirements
Install the models and run your first simulation.

- ROS 2 Lyrical on Ubuntu 26.04
- Gazebo Jetty, installed as ROS 2 Lyrical's `ros_gz` dependency (the
packages talk to Gazebo only through `ros_gz`)
```{toctree}
:maxdepth: 1

## Installation

Into a colcon workspace:

```bash
mkdir -p ~/ws/src
cd ~/ws/src
git clone https://github.com/HonuRobotics/holybro_models.git
cd ~/ws
rosdep update
rosdep install --from-paths src --ignore-packages-from-source --default-yes
colcon build --merge-install
source install/setup.bash
```

The project standard is `colcon build --merge-install`; the default isolated
layout also works. Binary debs are planned once the packages are released
into the ROS ecosystem; a released vehicle can then be reconfigured without
rebuilding (see [Change the loadout](../how-to/index.md)).

## First simulation

```bash
ros2 launch x500_gazebo sim.launch.xml
```

Gazebo opens with the X500 resting on its landing gear. The model carries
no control layer: the rotors idle until something publishes
`gz.msgs.Actuators` on `/x500/command/motor_speed` (that is the autopilot's
job; PX4 SITL, ArduPilot SITL or a custom controller). The flight sensors
publish right away:

```bash
ros2 topic echo /x500/imu --once
ros2 topic echo /x500/gps/fix --once
```

To see the model in RViz instead:

```bash
ros2 launch x500_description display.launch.xml
requirements
installation
first-simulation
```
45 changes: 45 additions & 0 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Installation

## From source

Into a colcon workspace:

```bash
mkdir -p ~/ws/src
cd ~/ws/src
git clone https://github.com/HonuRobotics/holybro_models.git
cd ~/ws
rosdep update
rosdep install --from-paths src --ignore-packages-from-source --default-yes
colcon build --merge-install
source install/setup.bash
```

```{tip}
`rosdep update` refreshes the dependency database; skipping it in fresh
containers is the usual cause of "Cannot locate rosdep definition" errors.
```

The project standard is `colcon build --merge-install` (one deb style prefix,
the layout users get from binary installs). The default isolated layout also
works if you prefer it.

The build generates the default vehicle artifacts from the vehicle's config
(the URDF, the composed Gazebo model, the ros_gz bridge config).

## From ROS packages (debs)

Binary packages (`ros-<distro>-x500-gazebo`, `ros-<distro>-x500-description`,
`ros-<distro>-holybro-parts`) are planned for the ROS build farm and are not
published yet. When they are, installation is:

```bash
sudo apt install ros-lyrical-x500-gazebo
source /opt/ros/lyrical/setup.bash
ros2 launch x500_gazebo sim.launch.xml
```

Nothing under `/opt/ros` is meant to be edited. The default vehicle is baked
into the packages; a custom config is a YAML file anywhere on disk passed
to the launch (`config_file:=`), which regenerates every artifact at launch
time ([Configuration](../vehicles/x500/configuration.md)).
7 changes: 7 additions & 0 deletions docs/getting-started/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Requirements

| | Supported |
|---|---|
| OS | Ubuntu 26.04 |
| ROS 2 | [Lyrical](https://docs.ros.org/en/lyrical/) |
| Gazebo | [Jetty](https://gazebosim.org/docs/jetty), installed as ROS 2 Lyrical's `ros_gz` dependency (the default pairing); no separate Gazebo install needed |
3 changes: 2 additions & 1 deletion docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ the problem and fail the build or the launch.

## Topics

See [X500: Sensors and Driving](../vehicles/x500.md). `/clock` and
See the X500 [Sensors](../vehicles/x500/sensors.md) and
[Actuators](../vehicles/x500/actuators.md) pages. `/clock` and
`/joint_states` are always bridged; every part topic follows
`/<namespace>/<instance>/<suffix>` on both sides.

Expand Down
4 changes: 2 additions & 2 deletions docs/vehicles/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
```{toctree}
:hidden:

x500
x500/index
```

| Vehicle | Packages | Manual |
|---|---|---|
| Holybro X500 V2 quadcopter | `x500_description`, `x500_gazebo` | [X500](x500.md) |
| Holybro X500 V2 quadcopter | `x500_description`, `x500_gazebo` | [X500](x500/index.md) |
73 changes: 0 additions & 73 deletions docs/vehicles/x500.md

This file was deleted.

39 changes: 39 additions & 0 deletions docs/vehicles/x500/actuators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Actuators

Actuators are parts fitted into slots, exactly like the sensors. The
vehicle's slots and their accepted types are in the
[configuration page](configuration.md), and new parts can be added
following the [Add a part](../../how-to/index.md) guide.

## Available actuators

| Actuator | Part | Slot | Fitted by default |
|---|---|---|---|
| 1345 propellers, counter clockwise | `prop_1345_ccw` | `rotor_0`, `rotor_1` | yes |
| 1345 propellers, clockwise | `prop_1345_cw` | `rotor_2`, `rotor_3` | yes |

## Actuators ROS API

There is none, deliberately. On a multicopter the per rotor outputs only
make sense downstream of an attitude controller, so the autopilot (PX4
SITL, ArduPilot SITL or a custom controller) is the control layer and it
talks to the Gazebo motor bus directly. The marine vehicles (BlueBoat,
BlueROV2) expose a normalized -1..1 `throttle` topic per thruster, the
ArduPilot output convention; the X500's equivalent normalized layer is
the autopilot itself. Rotor joint states are bridged to `/joint_states`
so RViz animates the props.

## Gazebo transport API

| gz Topic | Description | Message type |
|---|---|---|
| `/x500/command/motor_speed` | Angular velocity per rotor (rad/s), indexed by the rotor number | `gz.msgs.Actuators` |

To spin the rotors by hand, with no autopilot:

```bash
gz topic -t /x500/command/motor_speed -m gz.msgs.Actuators -p 'velocity: [700, 700, 700, 700]'
```

Keep the rotor instances named `rotor_0` .. `rotor_3`: the bus indexes
actuators by that trailing number.
28 changes: 28 additions & 0 deletions docs/vehicles/x500/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Configuration

The X500 needs no configuration: every slot the parts declare fills
itself with its default. The loadout config
(`x500_description/config/x500.yaml`, or any file passed as
`config_file:=`) states differences only.

## Payload

Sensors and actuators are fitted into slots, one config entry each. The
fitted options and their topics live in [Sensors](sensors.md) and
[Actuators](actuators.md); the slots are:

| Slot | Accepts | Default |
|---|---|---|
| `rotor_0` .. `rotor_3` | the matching 1345 propeller | fitted |
| `battery` | `battery_4s` | fitted |
| `gps` | `gps_mast` | fitted |
| `companion` | `companion_computer` | empty |
| `gimbal` | `gimbal_camera` | empty |

Keep the rotor instances named `rotor_0` .. `rotor_3`: the motor command
bus indexes actuators by that number, and the expansion fails loudly on a
rotor whose name does not end in its actuator number. Slot entries, free
placements, ad hoc slots and topic overrides follow the schema in
[Reference](../../reference/index.md); the instance key is `of:`, not
`on:`. Mistakes fail the build or the launch with a message naming the
problem.
21 changes: 21 additions & 0 deletions docs/vehicles/x500/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# X500

The [Holybro X500 V2](https://holybro.com/products/x500-v2-kits) development
kit quadcopter, assembled from the `holybro_parts` library.

```{toctree}
:maxdepth: 1

running
actuators
sensors
configuration
```

## The default vehicle

The default loadout is the airframe with its four 1345 propellers (PX4
quad X spin: rotors 0 and 1 counter clockwise, 2 and 3 clockwise), the 4S
battery and the GPS mast. Everything else in the catalog (companion
computer, gimbal camera) can be fitted, and the defaults swapped or left
off ([Configuration](configuration.md)).
35 changes: 35 additions & 0 deletions docs/vehicles/x500/running.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Running the simulation

```bash
ros2 launch x500_gazebo sim.launch.xml
```

Launches the vehicle in its default configuration: every artifact of the
loadout is generated at start (URDF, composed model, bridge config, into
a directory under `$ROS_HOME`), the model is spawned as `x500` into the
ground world and the ROS bridge comes up with it. The vehicle rests on
its landing gear; the rotors idle until an autopilot publishes on the
motor bus ([Actuators](actuators.md)).

To run a custom vehicle instead, pass a loadout file with `config_file:=`;
the [configuration page](configuration.md) lists the slots and
[Change the loadout](../../how-to/index.md) walks through writing one.

## Choosing the world

By default the vehicle is spawned into the vehicle free ground world
(`x500_ground.sdf`). The `world:=` argument swaps the environment without
changing anything else about the simulation: pass any vehicle free world
SDF:

```bash
ros2 launch x500_gazebo sim.launch.xml world:=/path/my_world.sdf
```

## In RViz

To see the model in RViz:

```bash
ros2 launch x500_description display.launch.xml
```
36 changes: 36 additions & 0 deletions docs/vehicles/x500/sensors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Sensors

Sensors are parts fitted into slots, with one exception: the IMU,
barometer and magnetometer belong to the airframe itself, as the
autopilot carries them on the real vehicle. The slots and their accepted
types are in the [configuration page](configuration.md), and new sensor
parts can be added following the [Add a part](../../how-to/index.md)
guide.

## Available sensors

| Sensor | Part | Slot | Fitted by default |
|---|---|---|---|
| IMU, barometer, magnetometer | the airframe | | yes |
| GPS | `gps_mast` | `gps` | yes |

## Sensors ROS API

### Flight sensors

| ROS Topic | Description | Message type |
|---|---|---|
| `/x500/imu` | Body IMU | [sensor_msgs/msg/Imu](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/Imu.html) |
| `/x500/air_pressure` | Barometer | [sensor_msgs/msg/FluidPressure](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/FluidPressure.html) |
| `/x500/mag` | Magnetometer | [sensor_msgs/msg/MagneticField](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/MagneticField.html) |

### GPS

| ROS Topic | Description | Message type |
|---|---|---|
| `/x500/gps/fix` | Position fix | [sensor_msgs/msg/NavSatFix](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/NavSatFix.html) |

Topic bases follow `/<namespace>/<instance>/...`: empty the GPS slot and
its topic disappears, rename the instance and it follows, and per part
`topic` / `gz_topic` / `ros_topic` overrides in the config rename the
base.
Loading