This guide walks you through setting up the project and running your first simulation.
- Python 3.10+ (3.11 or 3.12 recommended)
- MuJoCo 3.0+ (automatically installed with
mujocopackage) - Git for version control
- 8GB+ RAM recommended for training
- Optional: Webots (for human tracking)
- Optional: ArduPilot SITL (for deployment/SITL workflows)
UV is a fast Python package manager.
# Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and setup
git clone https://github.com/brainnotincluded/NNPID.git
cd NNPID
# Inference-only (load trained models)
uv sync
# Full install (training + simulation + visualization)
uv sync --all-extras
# Activate environment
source .venv/bin/activate# Clone repository
git clone https://github.com/brainnotincluded/NNPID.git
cd NNPID
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# or
.venv\Scripts\activate # Windows
# Install package
pip install -e .
# Full install (training + simulation + visualization)
pip install -e ".[full]"git clone https://github.com/brainnotincluded/NNPID.git
cd NNPID
# Install with dev dependencies
pip install -e ".[dev,full]"# Test MuJoCo works
python -c "import mujoco; print(f'MuJoCo {mujoco.__version__}')"
# Test environment loads
python -c "from src.environments import YawTrackingEnv; env = YawTrackingEnv(); print('OK')"
# Run tests
pytest tests/ -vfrom src.core.mujoco_sim import MuJoCoSimulator
import numpy as np
# Create simulator
sim = MuJoCoSimulator("models/quadrotor_x500.xml")
# Reset at 1m height
sim.reset(position=np.array([0, 0, 1.0]))
# Hover (equal thrust on all motors)
hover_thrust = 0.62 # ~mg/max_thrust for 2kg drone
# Simulate 100 steps
for i in range(100):
sim.step(np.array([hover_thrust] * 4))
state = sim.get_state()
if i % 20 == 0:
print(f"Step {i}: z={state.position[2]:.2f}m")from src.environments import YawTrackingEnv
# Create environment
env = YawTrackingEnv(render_mode="human")
# Run episode
obs, info = env.reset(seed=42)
for step in range(500):
# Random action
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
if step % 50 == 0:
print(f"Step {step}: yaw_error={info['yaw_error']:.2f} rad")
if terminated or truncated:
break
env.close()# Interactive visualization
python scripts/visualize_mujoco.py \
--mode interactive \
--model runs/<run_name>/best_model
# Record a video
python scripts/visualize_mujoco.py \
--mode video \
--model runs/<run_name>/best_model \
--output runs/visualizations/demo.mp4# Quick training (5 minutes)
python scripts/train_yaw_tracker.py --timesteps 50000
# Check results
ls runs/NNPID/
├── src/
│ ├── core/ # MuJoCo physics
│ ├── environments/ # Gym environments
│ ├── controllers/ # PID & NN controllers
│ └── utils/ # Helper functions
├── scripts/ # Run these!
├── models/ # MuJoCo XML models
├── config/ # YAML configurations
└── runs/ # Training outputs
- Train a model: See Training Guide
- Use trained models: See Using Trained Models
- Deploy to SITL: See SITL Integration
- Webots tracking: See Quickstart
- Deep dive: See Webots Human Tracking
- Understand code: See Architecture
# macOS
brew install glfw
# Ubuntu
sudo apt-get install libglfw3-devMake sure you installed the package:
pip install -e .Use parallel environments:
python scripts/train_yaw_tracker.py --n-envs 8- Check Architecture Guide for code structure
- Open an issue on GitHub for bugs
- Read MuJoCo docs: https://mujoco.readthedocs.io/