Simulation Module¶
ArduPilot SITL + Gazebo Harmonic simulation for Nectar drone development and testing, over either transport (MAVROS or direct MAVLink).
How It Works¶
ArduPilot SITL runs the full ArduCopter firmware on the host machine. Gazebo Harmonic provides physics and sensor simulation. The ArduPilotPlugin bridges Gazebo physics to SITL via JSON over UDP (port 9002). SITL exposes two MAVLink endpoints: TCP 5760 (SERIAL0, for MAVROS) and TCP 5762 (SERIAL1, for a direct pymavlink client / MavlinkDrone) — so both transports can run against the same simulator. The ros_gz_bridge converts Gazebo sensor data to ROS 2 messages.
flowchart LR
subgraph sitl [ArduPilot SITL]
ArduCopter["arducopter binary"]
end
subgraph gazebo [Gazebo Harmonic]
Physics["Physics + Sensors"]
ArduPlugin["ArduPilotPlugin"]
GUI["GUI: 3D + ImageDisplay + TopicEcho"]
end
subgraph bridge [ros_gz_bridge]
SensorBridge["Cameras + Lidar"]
PoseBridge["Pose bridge (indoor)"]
end
subgraph ros2 [ROS 2]
MAVROS["MAVROS"]
VisionSource["gz_vision_source (indoor)"]
VisionNode["vision_pose_node (mavros)"]
SDK["Nectar SDK / MavrosDrone | MavlinkDrone"]
end
ArduPlugin -->|"JSON UDP:9002"| ArduCopter
ArduCopter -->|"TCP:5760 (MAVROS)"| MAVROS
ArduCopter -->|"TCP:5762 (direct MAVLink)"| SDK
Physics --> SensorBridge
SensorBridge --> SDK
PoseBridge --> VisionSource
VisionSource -->|"/visual_slam/tracking/vo_pose_covariance"| VisionNode
VisionSource -->|"/visual_slam/tracking/vo_pose_covariance"| SDK
VisionNode -->|"/mavros/vision_pose/pose_cov"| MAVROS
MAVROS --> SDK
Two Environments¶
Outdoor (GPS)¶
- World:
outdoor_field.sdf-- open field with obstacle zone at x=13..18, fly-through gate - GPS via
gz-sim-navsat-systemplugin with WGS84 coordinates (Canberra default) - ArduPilot params:
copter.parm+gazebo.parm(rangefinder enabled) - Config preset:
SITL_GAZEBO_CONFIG(PoseSource.GPS)
Indoor (Vision)¶
- World:
indoor_room.sdf— 20x20x12m room, drone at x=-5 - No GPS; EKF3 ExternalNav via the same vision bridges as hardware (details: localization README — SITL)
- Params:
copter.parm+gazebo.parm+indoor.parm - Config:
SITL_VISION_CONFIG(PoseSource.VISION)
Simulated Sensors¶
| Real sensor | Gazebo sensor | Topic (ROS 2) | Notes |
|---|---|---|---|
| RealSense D435i (front) | rgbd_camera |
/front_camera/image, /front_camera/depth_image, /front_camera/points |
640x480, RGB + depth + point cloud |
| Arducam (down) | camera |
/down_camera |
640x480 RGB, downward-facing |
| TFLuna lidar (down) | SITL simulated sonar | /mavros/rangefinder/rangefinder |
RNGFND1_TYPE=1, ground distance from physics |
| TFLuna lidar (down) | gpu_lidar |
/lidar/range |
Direct LaserScan via Gazebo, 1-sample rangefinder |
The table above is the ArduPilot world. On both firmwares the SDK reads the
downward rangefinder from /mavros/rangefinder/rangefinder: ArduPilot derives it
from the SITL sonar, while PX4 fuses the x500_nectar gz gpu_lidar into a
distance_sensor and streams it as MAVLink DISTANCE_SENSOR (see
simulation/config/px4_config_sitl.yaml). ArduPilot additionally exposes the raw
Gazebo gpu_lidar LaserScan on /lidar/range.
Gazebo GUI¶
Both world SDFs include built-in GUI plugins (no extra windows needed):
- ImageDisplay panels for front RGB, front depth, and down camera (start collapsed, click to expand)
- TopicEcho for viewing any Gazebo transport topic live
- WorldStats showing sim time, real time, RTF
Installation¶
ArduPilot — clones ~/ardupilot + builds ArduCopter SITL, then installs Gazebo Harmonic + ArduPilotPlugin + ros_gz_bridge:
PX4 — clones ~/PX4-Autopilot + builds px4_sitl + Gazebo, and symlinks the Nectar shared assets (x500_nectar, outdoor_field_scenery, outdoor_field_px4) into the PX4 tree. Add ARGS=--native for the uXRCE-DDS path:
Both:
Then reload your shell: source ~/.bashrc.
Usage¶
One pattern for both firmwares. The two-terminal split is unavoidable (the autopilot SITL and the ROS stack are separate processes), so it is symmetric:
- Terminal 1 —
sim-start: the simulator (ArduPilot SITL; for PX4 also Gazebo). - Terminal 2 —
sim-bridge: the ROS stack (Gazebo + bridges for ArduPilot; for PX4, MAVROS, MicroXRCE-DDS, or camera-only depending onPROTOCOL).
Choose the scenario with three variables (defaults ardupilot / outdoor /
mavlink, so bare make sim-start + make sim-bridge = ArduPilot outdoor over
direct MAVLink). ENV must match between the two terminals.
FIRMWARE=ardupilot|px4ENV=outdoor|indoorPROTOCOL=mavlink(direct pymavlink, default) |mavros. For PX4,ddsselects the native uXRCE-DDS agent.
| Scenario | Terminal 1 | Terminal 2 | Mission config |
|---|---|---|---|
| ArduPilot outdoor, direct MAVLink | make sim-start FIRMWARE=ardupilot ENV=outdoor |
make sim-bridge FIRMWARE=ardupilot ENV=outdoor |
MavlinkDrone / MAVLINK_SITL_GAZEBO_CONFIG |
| ArduPilot outdoor, MAVROS | (same Terminal 1) | make sim-bridge FIRMWARE=ardupilot ENV=outdoor PROTOCOL=mavros |
MavrosDrone / SITL_GAZEBO_CONFIG |
| ArduPilot indoor, direct MAVLink | make sim-start FIRMWARE=ardupilot ENV=indoor |
make sim-bridge FIRMWARE=ardupilot ENV=indoor |
MavlinkDrone / MAVLINK_SITL_VISION_CONFIG |
| ArduPilot indoor, MAVROS | (same Terminal 1) | make sim-bridge FIRMWARE=ardupilot ENV=indoor PROTOCOL=mavros |
MavrosDrone / SITL_VISION_CONFIG |
| PX4 outdoor, direct MAVLink | make sim-start FIRMWARE=px4 ENV=outdoor |
make sim-bridge FIRMWARE=px4 ENV=outdoor |
Px4MavlinkDrone / PX4_MAVLINK_SITL_GAZEBO_CONFIG |
| PX4 outdoor, MAVROS | (same Terminal 1) | make sim-bridge FIRMWARE=px4 ENV=outdoor PROTOCOL=mavros |
Px4MavrosDrone / PX4_SITL_GAZEBO_CONFIG |
| PX4 outdoor, uXRCE-DDS | (same Terminal 1) | make sim-bridge FIRMWARE=px4 ENV=outdoor PROTOCOL=dds |
Px4DdsDrone / PX4_DDS_SITL_CONFIG |
| PX4 indoor, direct MAVLink | make sim-start FIRMWARE=px4 ENV=indoor |
make sim-bridge FIRMWARE=px4 ENV=indoor |
Px4MavlinkDrone / PX4_MAVLINK_SITL_VISION_CONFIG |
| PX4 indoor, MAVROS (external-nav) | (same Terminal 1) | make sim-bridge FIRMWARE=px4 ENV=indoor PROTOCOL=mavros |
Px4MavrosDrone / PX4_SITL_VISION_CONFIG |
| PX4 indoor, uXRCE-DDS | (same Terminal 1) | make sim-bridge FIRMWARE=px4 ENV=indoor PROTOCOL=dds |
Px4DdsDrone / PX4_DDS_SITL_VISION_CONFIG |
- ArduPilot: Terminal 1 runs the SITL physics; Terminal 2 launches Gazebo +
ros_gz_bridge. DefaultPROTOCOL=mavlinkstartsvision_pose_nodeon SERIAL0 (tcp5760) indoors; the mission uses SERIAL1 (tcp5762). Activate the nectar venv (nectar-activate) before Terminal 2 so pymavlink is available — otherwise the feeder exits and5762stays closed.PROTOCOL=mavrosadds MAVROS on SERIAL0 plusvision_pose_node. - Connection strings differ by transport: MAVROS uses a URL (
tcp://host:port,udp://...); the direct-MAVLinkMavlinkDrone(pymavlink) uses a bare string (tcp:127.0.0.1:5762,udp:host:port, or a serial path like/dev/ttyUSB0). Thetcp://URL form is also accepted forMavlinkDroneand normalized. - PX4: Terminal 1 (
start_px4.sh) runs PX4 and its Gazebo. Terminal 2 runs bridges. Offboard API is UDP14540. IndoorPROTOCOL=mavlinkuses mission-owned feed (auto_vision_feedonPX4_MAVLINK_SITL_VISION_CONFIG) because SITL exposes a single offboard endpoint. - PX4 uXRCE-DDS (
PROTOCOL=dds): Terminal 2 runsMicroXRCEAgent(udp4 :8888); outdoor leaves the agent in the foreground. Indoor also startspx4_sitl.launch.py vision:=true backend:=ddsso GT→VSLAM→VehicleOdometryreaches EKF2. One-time setup:make sim-install FIRMWARE=px4 ARGS=--native(buildspx4_msgs+ the agent).px4_msgsmust match the PX4 firmware (topics are versioned, e.g.vehicle_status_v4). - Indoor: both firmwares use
gz_vision_source→ vision bridges (see localization SITL). - Forward extra launch/script args with
ARGS=..., e.g. a one-off mavros toggle or rangefinder test world:
- Custom mission arenas (recommended): competition packages ship scenery only (
model.config+model.sdf+ meshes). Nectar composes the vehicle stack (plugins, iris, cameras, lidar).ENVselects indoor ExternalNav vs outdoor GPS; map and spawn are launch args:
make sim-start FIRMWARE=ardupilot ENV=indoor
make sim-bridge FIRMWARE=ardupilot ENV=indoor \
ARGS='scenery:=model://my_arena spawn_pose:="-5 0 0.195 0 0 0" resource_path:=/path/to/pkg/simulation/models'
| Arg | Role |
|---|---|
world:=outdoor\|indoor |
Compose from Nectar vehicle template (+ stock scenery if scenery empty) |
scenery:=model://name |
Replace stock scenery with a mission model |
spawn_pose:="x y z r p y" |
Iris pose (degrees); empty = template default |
resource_path:=a:b |
Extra dirs on GZ_SIM_RESOURCE_PATH (mission simulation/models) |
world:=/abs/path.sdf |
Escape hatch: full custom world (must embed drone/sensors yourself). Pass vision:=true for indoor ExternalNav — path worlds do not auto-enable vision. |
Composed worlds use fixed names nectar_indoor / nectar_outdoor (pose topic /world/<name>/dynamic_pose/info). Full custom worlds use the SDF <world name="...">. Mission packages that only supply scenery must not hard-code iris/cameras in their SDF.
- Headless ArduPilot without Gazebo (pure MAVROS): run
./scripts/simulation/start_sitl.shthenros2 launch nectar sitl.launch.pydirectly.
Run
make sim-stopbefore relaunching Terminal 2 — it clears every simulation process for both firmwares (arducopter/px4, Gazebo, MAVROS, bridges, vision nodes).
Shared-world architecture¶
Nectar owns the vehicle stack; missions own scenery.
simulation/templates/{indoor,outdoor}_vehicle.sdf.in— ArduPilot compose templates (plugins, iris, Nectar cameras/lidar). Launch substitutes scenery + spawn.simulation/models/indoor_room_scenery/— stock 20×20×12 m indoor room + obstacles.simulation/models/outdoor_field_scenery/— outdoor gate + obstacles. Also used byoutdoor_field.sdf/outdoor_field_px4.sdf.simulation/models/x500_nectar/— PX4x500+ matched sensors. Outdoor/indoor PX4 use shared scenery via include.simulation/worlds/outdoor_field_px4.sdf— scenery-only world for PX4 (no world<plugin>tags; PX4'sserver.configinjects systems). GPS origin near-zero declination (lat 0, lon 40), not ArduPilot's Canberra — see magnetometer notes in prior docs (gz-sim#2536).simulation/worlds/indoor_room_px4.sdf— indoor scenery-only world for PX4 (sameindoor_room_scenery). GT pose comes from PosePublisher onx500_nectar(Gazebo 8 requires model-level attachment; 50 Hz; spawned asx500_nectar_0).
Mission package layout:
No iris, cameras, or Gazebo world plugins in the mission package.
install_px4.sh symlinks Nectar assets (x500_nectar, outdoor/indoor scenery + worlds) into PX4's Tools/simulation/gz/{models,worlds} so PX4's launcher can find them while the source of truth stays in nectar-sdk/. start_px4.sh --autostart reuses PX4's existing 4001 (x500) airframe via PX4_SYS_AUTOSTART, so no PX4-tree airframe file is added. Indoor auto-loads params/px4_indoor.env and spawns at PX4_GZ_MODEL_POSE=-5,0,0.2. Outdoor auto-loads params/px4_outdoor.env (restores GNSS EKF after indoor EKF2_* values persist in SITL parameters.bson). Outdoor SITL also exports NAV_DLL_ACT=0, NAV_RCL_ACT=0, and COM_RCL_EXCEPT=4 so headless OFFBOARD can arm without RC/GCS (PX4 offboard SITL).
Stop all¶
One stop for both firmwares: kills arducopter, PX4 (px4_sitl/bin/px4), MicroXRCEAgent, Gazebo, MAVROS, ros_gz_bridge, gz_vision_source, and vision_pose_node processes.
Verify sensors¶
| Check | Command |
|---|---|
| State | ros2 topic echo /mavros/state --once |
| GPS (outdoor) | ros2 topic echo /mavros/global_position/global --once --qos-reliability best_effort |
| Vision pose (indoor) | ros2 topic echo /mavros/vision_pose/pose_cov --once |
| Rangefinder | ros2 topic echo /mavros/rangefinder/rangefinder --once |
| Front camera | ros2 topic echo /front_camera/image --once |
| Depth | ros2 topic echo /front_camera/depth_image --once |
Multi-orientation rangefinders¶
rangefinder_test.sdf places an iris with front and back single-ray lidars
between two walls. The iris_with_rangefinders model forwards the front/back
lidars to ArduPilot as rng_2/rng_3, and rangefinder_test.parm exposes them
as RNGFND2/3 (orientations forward/back). The downward rangefinder
(RNGFND1, orientation down) stays on the analog SITL sonar from gazebo.parm:
on the ground the airframe is only ~0.2 m tall, so a downward GPU lidar reads
below its minimum range, while the sonar reports vehicle height above terrain
reliably. ArduPilot emits one DISTANCE_SENSOR per instance, accessible through
drone.distance_sensors and drone.get_distance(orientation).
Terminal 1 — SITL with the three rangefinders:
./scripts/simulation/start_sitl.sh --gazebo \
--params nectar/simulation/params/rangefinder_test.parm
Terminal 2 — Gazebo (and MAVROS) with the test world:
Terminal 3 — inspect the readings (MAVROS topics):
ros2 topic echo /mavros/rangefinder/rangefinder --once
ros2 topic echo /mavros/distance_sensor/rangefinder/front --once
In code, both transports expose every reported unit via drone.distance_sensors
and drone.get_distance(orientation) (the downward unit also updates
drone.rangefinder); see the vehicle core README.
The MAVROS path relies on the distance_sensor plugin entries in
config/apm_config_sitl.yaml (rangefinder/rangefinder, rangefinder/front,
rangefinder/back) mapped to orientations.
Configuration Presets¶
Defined in nectar/control/config.py:
| Preset | Transport | Port | PoseSource | Lidar | Use case |
|---|---|---|---|---|---|
SITL_CONFIG |
mavros | 5760 | GPS | No | Headless SITL, no sensors |
SITL_GPS_CONFIG |
mavros | 5760 | GPS | No | Headless SITL with GPS |
SITL_GAZEBO_CONFIG |
mavros | 5760 | GPS | Yes | Gazebo outdoor |
SITL_VISION_CONFIG |
mavros | 5760 | VISION | Yes | Gazebo indoor |
MAVLINK_SITL_CONFIG |
mavlink | 5760 | GPS | No | Headless SITL, direct pymavlink |
MAVLINK_SITL_GAZEBO_CONFIG |
mavlink | 5762 | GPS | No | Gazebo outdoor, direct (SERIAL1, alongside MAVROS) |
MAVLINK_SITL_VISION_CONFIG |
mavlink | 5762 | VISION | No | Gazebo indoor; feeder SERIAL0 / 5760 |
PX4_SITL_CONFIG |
px4 | 14540 | GPS | No | PX4 SITL headless (offboard over MAVROS) |
PX4_SITL_GAZEBO_CONFIG |
px4 | 14540 | GPS | Yes | PX4 SITL + Gazebo (x500_nectar, outdoor) |
PX4_SITL_VISION_CONFIG |
px4 | 14540 | VISION | Yes | PX4 SITL indoor (indoor_room_px4 + gz_vision_source → EKF2) |
PX4_MAVLINK_SITL_CONFIG |
px4_mavlink | 14540 | GPS | No | PX4 SITL headless, direct pymavlink |
PX4_MAVLINK_SITL_GAZEBO_CONFIG |
px4_mavlink | 14540 | GPS | Yes | PX4 SITL + Gazebo (x500_nectar, outdoor), direct pymavlink |
PX4_MAVLINK_SITL_VISION_CONFIG |
px4_mavlink | 14540 | VISION | Yes | PX4 SITL indoor; mission-owned vision feed (single offboard UDP) |
PX4_DDS_SITL_CONFIG |
px4_dds | 8888 | GPS | Yes | PX4 SITL native uXRCE-DDS (MicroXRCEAgent on 8888), outdoor |
PX4_DDS_SITL_VISION_CONFIG |
px4_dds | 8888 | VISION | No | PX4 SITL indoor uXRCE-DDS (VehicleOdometry EV) |
from nectar.control import (
DroneFactory,
SITL_GAZEBO_CONFIG,
MAVLINK_SITL_GAZEBO_CONFIG,
PX4_SITL_GAZEBO_CONFIG,
PX4_MAVLINK_SITL_GAZEBO_CONFIG,
)
Outdoor over MAVROS (port 5760):
Outdoor over direct MAVLink (port 5762, sim-bridge ... PROTOCOL=mavlink):
PX4 over MAVROS (offboard UDP 14540, sim-start/sim-bridge FIRMWARE=px4 ENV=outdoor):
PX4 over direct pymavlink (offboard UDP 14540, sim-bridge ... PROTOCOL=mavlink):
Test Suite¶
Per-distro outdoor protocol status lives in docs/COMPATIBILITY.md (Simulation section). Tier-3 gate per protocol: make verify-sitl FIRMWARE=<ardupilot|px4> PROTOCOL=<mavros|mavlink|dds> — maps to the scenario rows below.
sitl_test.py runs atomic navigation tests. Each test starts from a clean hover and verifies a specific capability.
Usage¶
# All outdoor tests over MAVROS (37 tests, tcp 5760)
python3 nectar/nectar/examples/simulation/sitl_test.py
# Same suite over direct pymavlink (MavlinkDrone, tcp 5762)
python3 nectar/nectar/examples/simulation/sitl_test.py --mavlink
# Indoor-compatible subset (vision config, skips the 5 GPS-only tests -> 32 tests)
python3 nectar/nectar/examples/simulation/sitl_test.py --indoor
# Land between tests for a full reset
python3 nectar/nectar/examples/simulation/sitl_test.py --fresh pid_fwd
# Specific tests / a group / list everything
python3 nectar/nectar/examples/simulation/sitl_test.py pid_fwd setpoint_fwd
python3 nectar/nectar/examples/simulation/sitl_test.py --group vel
python3 nectar/nectar/examples/simulation/sitl_test.py --list
Flags: --mavlink (direct pymavlink on tcp 5762), --px4 (PX4 over MAVROS, offboard on udp 14540), --indoor (vision config, skip GPS-only tests), --fresh (land between tests).
Test groups¶
| Group | Tests | Description |
|---|---|---|
vel |
vel_fwd, vel_lat, vel_up, vel_yaw, vel_takeoff, vel_world, vel_world_north, vel_world_rotated, brake | Velocity in BODY/WORLD/TAKEOFF frames |
pid |
pid_fwd, pid_lat, pid_alt, pid_yaw | PID navigation with raw GPS |
pid_local |
pid_local_fwd, pid_local_lat, pid_local_yaw | PID navigation with EKF local position |
setpoint |
setpoint_fwd, setpoint_lat, setpoint_yaw | Local position setpoint publishing |
setpoint_global |
setpoint_global, setpoint_global_yaw | GPS global setpoint (outdoor only) |
wpnav |
setpoint_wpnav | AC_WPNav waypoint setpoint |
rtl |
rtl_pid, rtl_ardupilot | Return to launch |
yaw |
vel_yaw, pid_yaw, pid_local_yaw, setpoint_yaw, setpoint_global_yaw, yaw_direction, yaw_takeoff_ref | Yaw handling across methods |
world |
vel_world, vel_world_north, vel_world_rotated | WORLD-frame velocity |
nav |
pid_fwd, pid_lat, pid_local_fwd, pid_local_lat | Core PID navigation |
compound |
sequential, takeoff_ref | Multi-step sequences |
square |
sq_pid, sq_pid_takeoff, sq_pid_local, sq_setpoint, sq_setpoint_global, sq_wpnav | 3m square patterns |
Pre-flight tests (sensors, heading_enu) run without takeoff. GPS-only tests (skipped with --indoor): heading_enu, setpoint_global, setpoint_global_yaw, sq_setpoint_global, rtl_ardupilot.
The set_speed test exercises MAV_CMD_DO_CHANGE_SPEED (horizontal/climb/descent). It is not
in the pre-flight set because ArduCopter accepts that command only in a nav-capable mode
(GUIDED), so it must run airborne.
ArduPilot Parameters¶
gazebo.parm (loaded for all Gazebo sessions)¶
| Parameter | Value | Purpose |
|---|---|---|
SIM_SONAR_SCALE |
10 | SITL sonar scaling factor |
RNGFND1_TYPE |
1 | Analog rangefinder driven by SIM_SONAR |
RNGFND1_SCALING |
10 | Voltage-to-distance scaling |
RNGFND1_PIN |
0 | Analog pin |
RNGFND1_MAX |
40 | Max range (m) |
RNGFND1_MIN |
0.10 | Min range (m) |
indoor.parm (loaded additionally for ArduPilot indoor)¶
| Parameter | Value | Purpose |
|---|---|---|
GPS1_TYPE |
0 | Disable GPS |
EK3_SRC1_POSXY |
6 | ExternalNav for XY position |
EK3_SRC1_VELXY |
6 | ExternalNav for XY velocity |
EK3_SRC1_POSZ |
1 | Barometer for Z (default) |
EK3_SRC1_YAW |
6 | ExternalNav for yaw |
VISO_TYPE |
1 | Enable visual odometry input |
ARMING_CHECK |
388598 | Disable GPS-related arming checks |
px4_indoor.env / px4_outdoor.env (via PX4_PARAM_*)¶
Indoor (indoor_room_px4):
| Parameter | Value | Purpose |
|---|---|---|
EKF2_GPS_CTRL |
0 | Disable GNSS aiding |
EKF2_EV_CTRL |
11 | EV h-pos + v-pos + yaw (no velocity) |
EKF2_HGT_REF |
3 | Height reference = Vision |
EKF2_MAG_TYPE |
5 | None (yaw from vision) |
COM_ARM_WO_GPS |
1 | Allow arming without GPS (SITL) |
Outdoor (outdoor_field_px4) restores stock GNSS defaults so a prior indoor run cannot leave EKF2_GPS_CTRL=0 in parameters.bson (PX4 env overrides):
| Parameter | Value | Purpose |
|---|---|---|
EKF2_GPS_CTRL |
7 | Lon/lat + alt + 3D velocity |
EKF2_EV_CTRL |
0 | No external vision |
EKF2_HGT_REF |
1 | Height reference = GPS |
EKF2_MAG_TYPE |
0 | Automatic magnetometer fusion |
COM_ARM_WO_GPS |
1 | PX4 default (allow with warning) |
Indoor vision¶
Ground-truth pose/twist → canonical VSLAM topics via gz_vision_source.py, then
the same vision_pose_node backends as hardware. Full notes (sim time, velocity,
send_speed): localization README — SITL.
On Jazzy, ros_gz may strip child_frame_id; the source falls back to
model_index (default 0).
Layout¶
Simulation assets (nectar/simulation/):
params/— SITL parameter files:gazebo.parm/indoor.parm(ArduPilot),px4_indoor.env/px4_outdoor.env(PX4 EKF2),rangefinder_test.parmconfig/— MAVROS bridge profiles:apm_config_sitl.yaml/apm_pluginlists_sitl.yaml(ArduPilot),px4_config_sitl.yaml/px4_pluginlists_sitl.yaml(PX4)models/—indoor_room_scenery,outdoor_field_scenery,iris_with_rangefinders,x500_nectartemplates/—indoor_vehicle.sdf.in,outdoor_vehicle.sdf.in(composed bysitl_gazebo.launch.py)worlds/—outdoor_field.sdf,outdoor_field_px4.sdf,indoor_room.sdf,indoor_room_px4.sdf,rangefinder_test.sdf
Install and start scripts (scripts/simulation/): install_sitl.sh, install_gazebo.sh,
install_px4.sh, start_sitl.sh, start_px4.sh, and gz_vision_source.py.
Launch files (nectar/launch/): sitl.launch.py (MAVROS-only), sitl_gazebo.launch.py
(ArduPilot Gazebo + ros_gz_bridge), px4_sitl.launch.py (PX4 bridge). The navigation test suite
is examples/simulation/sitl_test.py.