-
Notifications
You must be signed in to change notification settings - Fork 13
User guide
This guide explains how to run and customize the core PyChrono-based UAV simulator in this repository.
-
UAV Simulator Usage Guide
- What this guide covers
- 1. Overview
- 2. Prerequisites
- 3. How to launch a single simulation from the Command Line Interface (CLI)
- 4. Supported command line interface (CLI) choices
- 5. How to run simulations programmatically from Python (Python API)
- 6. How to use wrapper mode (batch runs)
- 7. Logs and outputs
- 8. Core config files to edit
- 9. Quick checklist ✅
- 10. How to plot results
- 11. Common issues and fixes
UAV_Sim_PyChrono is a high-fidelity PyChrono-based simulator designed for multi-rotor UAVs (uncrewed aerial vehicles) with an array of available control solutions. The control architecture is organized into an outer loop for translational dynamics and an inner loop for rotational dynamics, both governed by nonlinear equations of motion.
- Install PyChrono and project dependencies. Please follow the PyChrono installation guide
- Activate your environment before running anything:
conda activate chrono_v9Tip: The default name is chrono_v9 if you followed the guide. If you use a different environment name, replace chrono_v9 accordingly.
From the repository root:
python main.py
The visualization window will pop up showing the real-time simulation.
Note: The visualization has some issues on macOS with PyChrono 9.0.1. Please run the simulator with visualization off using
python main.py --visualize false
You can configure the simulator either by editing acsl_pychrono/config/config.py for consistent runs or by using CLI flags for a single run.
For example, to change the UAV type, we can modify config.py as follows:
class VehicleConfig:
# UAV types:
# "Q" -- Quadcopter
# "SQ" -- Small quadcopter
# "X8" -- X8-copter
uav_name: str = "X8"
Or run:
python main.py --uav X8Run a specific UAV and controller:
python main.py --uav X8 --controller MRACHeadless run for faster experimentation (recommended for macOS users):
python main.py --visualize falseSet simulation duration:
python main.py --simulation_duration 20Change trajectory and trajectory file:
python main.py \
--trajectory_type piecewise_polynomial_trajectory \
--trajectory_file rollercoaster_trajectory1p2.jsonEnable environment:
python main.py \
--include_environment true \
--environment_path environmentA/environmentA.pyEnable motor failure:
python main.py \
--apply_motor_failure true \
--motor_failure_time 2.0Add payload and configure drop behavior:
python main.py \
--add_payload true \
--payload_type two_steel_balls \
--drop_two_steel_balls true \
--two_steel_balls_drop_time 1.5Controller choices accepted by CLI:
-
PID: Proportional-integral-derivative control law -
MRAC: Classical model reference adaptive control MRAC -
TwoLayerMRAC: Two-layer MRAC -
FunnelMRAC: Funnel MRAC. An MRAC system with time-varying constraints on the plant model -
HybridMRAC: Hybrid MRAC. An MRAC system for nonlinear time-varying plant models that experience sudden switched in their equations of motion and trajectory -
HybridTwoLayerMRAC: Hybrid two-layer MRAC. A two-layer version of hybrid MRAC. -
NonAdaptiveEBCI: A two-layer hybrid MRAC system with an error-bounding term in the control law to enforce user-defined ultimate bounds on the tracking error
Trajectory choices accepted by CLI:
-
hover_trajectory: Take off and hover. Ideal for initial tests -
circular_trajectory: Circular trajectory as a constant altitude. Relatively easy to follow trajectory. -
rounded_rectangle_trajectory: Take off and follow a rectangular trajectory with smoothed turns. -
square_trajectory: Take off and follow a square trajectory at a constant altitude. Useful to challenge a controller when taking sharp turns. -
piecewise_polynomial_trajectory: Take off and follow a seventh-order polynomial for minimum snap.
All trajectories are in params/user_defined_trajectory. You can also add new user-defined trajectories there.
Note: acsl_pychrono/config/config.py includes FunnelTwoLayerMRAC as a config option, but that is not exposed in the current CLI choices.
You can run simulations from Python via run_experiment(...) in main.py.
Example (similar to experiments.py):
from main import run_experiment
run_experiment(
uav="X8",
controller="PID",
visualize="false",
simulation_duration=10.0,
trajectory_type="piecewise_polynomial_trajectory",
trajectory_file="bean_trajectory0p2.json",
)This is useful for scripting multiple runs and custom experiment loops. 🚀
The purpose of this modality is to run batch simulations in parallel with ProcessPoolExecutor.
This modality uses up to wrapper_max_parallel workers (capped by the CPU's availability)
Wrapper mode is controlled by `config', not a CLI flag.
File:
acsl_pychrono/config/config.py
Set:
MissionConfig.wrapper_flag = True
Then run:
python main.pySingle-run mode output directory pattern:
logs/<YYYY>/<MM>/<YYYYMMDD>/<controller_type>/workspaces/
Wrapper mode output directory pattern:
logs/wrapper/<YYYY>/<MM>/ws_<timestamp>/
Each simulation writes a MATLAB workspace file via Logging.saveMatlabWorkspaceLog(...).
Note: If you want a clean folder, please delete the subfolders like logs/<YYYY> or logs/wrapper instead of the entire logs folder. 🧹
Primary runtime defaults:
acsl_pychrono/config/config.py
Useful fields:
| Field | What it controls |
|---|---|
MissionConfig.simulation_duration_seconds |
Total simulation time in seconds for each run. |
MissionConfig.visualization_flag |
Enables or disables real-time rendering during simulation. |
MissionConfig.controller_type |
Selects the controller type used in the run (for example PID or MRAC variants). |
MissionConfig.trajectory_type |
Chooses which trajectory type the UAV should follow. |
MissionConfig.trajectory_data_path |
Points to the trajectory file used. |
MissionConfig.add_payload_flag |
Toggles payload attachment to include payload dynamics. |
MissionConfig.apply_motor_failure |
Enables a motor-failure event for fault-tolerance testing. |
MissionConfig.apply_wind_force |
Applies external aerodynamic force for disturbance testing. |
VehicleConfig.uav_name |
Selects the UAV platform model (for example X8). |
EnvironmentConfig.include |
Turns environment assets/colliders on or off in the simulation. |
EnvironmentConfig.model_relative_path |
Sets the environment model file to load when environment inclusion is enabled. |
Controller gains are configured in YAML files under the folder Controller_Gains included in each platform module.
Example for X8 MRAC gains:
acsl_pychrono/uav/X8/Controller_Gains/MRAC.yaml
Gains are typically formatted as scalars or scaling factors applied to matrices.
Each platform is a module with a predefined structure and naming convention that lives in the acsl_pychrono/uav/ folder.
To create, rename, delete and manage the integrty of each platform module, the uav_mutil.py utility is provided.
For more information about platforms, file structures and the management tool, please refer to the official wiki on How to Set Up A New UAV.
- Environment activated (
conda activate chrono_v9) -
main.pyruns with defaults - Controller and trajectory are valid
- Logs show up in the expected output folder
To visualize simulation performance, the ACSL-flightstack-accessories repository provides a MATLAB-based plotter.
Locate the .mat log files as discussed in Section 7, then move or copy them into ACSL-flightstack-accessories/pychrono/<YYYY>/<MM>/<YYYYMMDD>/[Name of Controller]/workspaces, which follows the simulator naming pattern.
Then add both _LOGS_PLOTTER and pychrono folders and their subfolders to the MATLAB path.

Open _LOGS_PLOTTER/PyChrono_PLOTTER.m, then modify the line 22, line 25 and line 29 as shown in the screenshot below matching the file path to load the log you want to inspect into the workspace.
For the plotter, instead of running the whole script, locate the function you want to run, click it, and use the keyboard shortcut Shift + Enter to run the selected part.

After loading the workspace, you should see this:

- Confirm you are in the correct Conda/Python environment.
- Confirm dependencies are installed using the following command inside the project environment (
chrono_v9):
conda list- If PyChrono is installed but not found, check
PYTHONPATHfor Chrono Python bindings.
For MacOS users, if you see the following output when running the simulator:

It is an issue with PyChrono 9.0.1 on MacOs, please run with --visualize false.
- Ensure trajectory file exists under
params/user_defined_trajectory. - Verify any environment path you pass via
--environment_pathis correct
UAV_Sim_PyChrono — A PyChrono-based high-fidelity simulator for UAVs
Developed by Mattia Gramuglia and Andrea L'Afflitto