Skip to main content

Drone-Planning

A motion planning library for the Holybro X500 V2 quadrotor with a pan-tilt gimbal camera. Same public API and module layout as its sister packages Fetch-Planning and Autolife-Planning — OMPL planners over a VAMP SIMD collision backend, FLASK kinodynamic planning and TOPP-RA time parameterization — so code can switch robots by changing a single import.

pip install drone-planning

Documentation: https://h-tr.github.io/Drone-Planning/


The robot

The model is PX4's official Gazebo x500_gimbal (PX4-gazebo-models: x500 + gimbal), converted to URDF with its meshes and dimensions (scripts/px4_sdf_to_urdf.py, see docs/robot.md). The flight controller holds roll and pitch, so the body is a velocity-commanded point with a heading: 6 DOF.

Index Joint Group Range
0 base_x_joint base −10 … 10 m (virtual, world frame)
1 base_y_joint base −10 … 10 m
2 base_z_joint base 0 … 10 m (z up)
3 base_yaw_joint base −π … π (counter-clockwise from +x)
4 cgo3_vertical_arm_joint gimbal pan, −π … π (positive turns right)
5 cgo3_camera_joint gimbal tilt, −135° … 45° (positive looks up)

Planning subgroups (drone_planning.x500.PLANNING_SUBGROUPS):

  • x500_base — 4 DOF: (x, y, z, yaw), gimbal held
  • x500_whole_body — 6 DOF: body + gimbal pan and tilt (alias x500)

The collision model is 126 spheres (foam → SRDF → cricket, the template's pipeline), covering every link's original PX4 mesh (the rotor discs as swept by the spinning propellers) except for thin slivers; tests/test_collision_model.py checks the coverage. Point obstacles are checked as points: the spheres are the margin.

Kinodynamic limits are PX4 v1.17 default parameters (drone_planning/x500.py):

Velocity Acceleration
horizontal (x, y), norm 12 m/s MPC_XY_VEL_MAX 5 m/s² MPC_ACC_HOR_MAX
vertical z −1.5 … 3 m/s MPC_Z_VEL_MAX_DN/UP −3 … 4 m/s² MPC_ACC_DOWN/UP_MAX
yaw 60 °/s MPC_YAWRAUTO_MAX 20 °/s² MPC_YAWRAUTO_ACC
gimbal pan / tilt 30 °/s MNT_RATE_YAW/PITCH 97 / 300 rad/s² (model torque cap)

Usage

import numpy as np
from drone_planning.planning import create_planner
from drone_planning.types import KinodynamicConfig, PlannerConfig

planner = create_planner(
    "x500_whole_body",
    config=PlannerConfig(
        planner_name="rrtc",
        time_limit=1.0,
        joint_limits={"base_x_joint": (-0.5, 5.5), "base_y_joint": (-2.0, 2.0),
                      "base_z_joint": (0.3, 2.7)},       # the workspace
    ),
    pointcloud=cloud,                                     # (N, 3) float32
)

start = np.array([0.0, 1.5, 2.2, -1.57, 0.0, 0.0])        # x, y, z, yaw, pan, tilt
goal = np.array([5.0, -1.5, 0.6, 3.14, 1.0, -1.2])

result = planner.plan(start, goal)                        # geometric path
if result.success:
    print(result.path.shape)

kino = planner.plan_kinodynamic(start, goal, config=KinodynamicConfig(time_limit=1.0))
times, q, qd, qdd = kino.trajectory.sample_uniform(dt=0.02)
# qd[:, :4] = (x_dot, y_dot, z_dot, yaw_rate): PX4 offboard velocity setpoints

Low-level API

The _ompl_vamp extension has the low-level API of the sister packages, for callers (e.g. PHANTOM) that drive it directly:

from drone_planning._ompl_vamp import KinodynamicSettings, OmplVampPlanner

planner = OmplVampPlanner()                               # full body, 6 DOF
planner.dimension()                                       # 6
lower, upper = planner.default_joint_limits()             # full-body order
planner.set_joint_limits(lower, upper)
planner.set_subgroup([0, 1, 2, 3], full_configuration)    # body; gimbal frozen
planner.add_pointcloud(points_float32_nx3, 0.0)           # replaces the cloud
result = planner.plan(start, goal, planner_name="rrtc", time_limit=1.0,
                      simplify=True, interpolate=False)
result.solved, result.path                                 # bool, (N, 4) array
result = planner.plan_kinodynamic(start, start_velocity, goal, 1.0, settings)

solved is true only for an exact solution (an approximate OMPL solution, which stops short of the goal, is not solved). MotionPlanner._kinodynamic_settings shows how KinodynamicSettings is filled from the PX4 limits.


Results

Planning times and success rates of RRT-Connect (plan()) and FLASK on the demo room are in docs/planning/kinodynamic.md, and the cost of a collision check in docs/planning/index.md.


Architecture

┌───────────────────────────────────────────────────────────────┐
│                   drone_planning/ (Python)                     │
│   create_planner(...) → MotionPlanner                          │
│     plan()  ·  plan_kinodynamic()  ·  validate_batch()         │
└────────┬───────────────────────────────────────────────────────┘
         │ one nanobind call
┌────────▼───────────────────────────────────────────────────────┐
│              _ompl_vamp  (C++/nanobind extension)              │
│  OMPL SimpleSetup, RealVectorStateSpace over the active joints │
│    RRT-Connect, RRT*, BIT*, AIT*, KPIECE, PRM, FMT, … (30)     │
│  FLASK: kinodynamic RRT-Connect, closed-form cubic edges       │
└────────┬───────────────────────────────────────────────────────┘
         │
┌────────▼───────────────────────────────────────────────────────┐
│              VAMP backend  (header-only, SIMD)                 │
│   vamp::robots::X500 (126 spheres), generated by cricket       │
│   point clouds in a CAPT built for Robot::max_radius           │
└────────────────────────────────────────────────────────────────┘

Project layout

Drone-Planning/
├── CMakeLists.txt              # two extensions: _ompl_vamp, _time_parameterization
├── pyproject.toml              # scikit-build-core
├── pixi.toml                   # conda env + build tasks
├── .gitmodules                 # vamp, ompl, cricket, foam
│
├── drone_planning/             # Python package (mirrors fetch_planning/)
│   ├── x500.py                 # 6-DOF X500 layout (joint groups, HOME, PX4 limits, …)
│   ├── types/                  # SE3Pose, PlannerConfig, KinodynamicConfig, …
│   ├── trajectory/             # TOPP-RA + FLASK trajectories
│   ├── kinematics/             # Pinocchio FK (e.g. the camera pose)
│   ├── planning/               # MotionPlanner, create_planner
│   ├── envs/                   # PyBullet scene wrapper
│   ├── utils/                  # rotations, PyBullet helpers, video recorder
│   └── resources/robot/x500/   # x500.urdf + x500_spherized.urdf + x500.srdf + meshes
│
├── ext/
│   ├── ompl_vamp/              # nanobind OMPL↔VAMP bridge + FLASK
│   │   └── include/vamp/robots/x500.hh   # generated by cricket
│   └── time_parameterization/  # vendored TOPP-RA C++ core (nanobind)
│
├── scripts/                    # build_robot.sh (PX4 SDF → URDF), spherize_robot.sh,
│                               # generate_fk.sh, cricket_configs/, render_videos/
├── examples/planning/          # motion, subgroup, kinodynamic, time parameterization
├── tests/                      # pytest suite
└── third_party/                # vamp, ompl, cricket, foam

Rebuild the robot model end to end with pixi run generate-fk (PX4 SDF → URDF → foam → cricket); it reproduces the committed files byte for byte.


Development

git clone --recursive https://github.com/H-tr/Drone-Planning.git
cd Drone-Planning
bash scripts/setup.sh        # pixi install, build cricket + foam
pixi run test                # pytest suite

Dependencies: cmake, ninja, a C++17 compiler, nanobind, Boost (serialization, filesystem), Eigen; pinocchio, CGAL, CppAD, inja for cricket; trimesh, pycollada, pymeshlab for the model conversion. Pixi installs all of them from conda-forge. Runtime (wheel): numpy, pin.

Wheels: pipx run cibuildwheel --platform linux (manylinux_2_34 and manylinux_2_28, CPython 3.10–3.14). Releases: pushing a v* tag runs .github/workflows/release.yml, which publishes to PyPI with Trusted Publishing (environment pypi).


License & attribution

  • The X500 model (meshes, poses, inertials) is from PX4-gazebo-models (BSD-3-Clause, © Rudis Laboratories; license in drone_planning/resources/robot/x500/LICENSE).
  • VAMP (Apache-2.0, KavrakiLab), OMPL (BSD-3-Clause), foam and cricket (MIT, CoMMALab).
  • The time parameterizer vendors the C++ core of toppra (MIT, © Hung Pham) unmodified under ext/time_parameterization/toppra/.
  • FLASK: Duong et al., "Ultrafast Sampling-based Kinodynamic Planning via Differential Flatness", T-RO 2026.

Metadata

Release files for drone-planning 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for drone-planning 0.1.0
File Actions
drone_planning-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.34+ x86-64 Details for drone_planning-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl
drone_planning-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details for drone_planning-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
drone_planning-0.1.0-cp313-cp313-manylinux_2_34_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.34+ x86-64 Details for drone_planning-0.1.0-cp313-cp313-manylinux_2_34_x86_64.whl
drone_planning-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for drone_planning-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
drone_planning-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.34+ x86-64 Details for drone_planning-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl
drone_planning-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details for drone_planning-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
drone_planning-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.34+ x86-64 Details for drone_planning-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl
drone_planning-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for drone_planning-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
drone_planning-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.34+ x86-64 Details for drone_planning-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl
drone_planning-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for drone_planning-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Total release size: 47.4 MB

Release files / drone_planning-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl

Download URL drone_planning-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl
Size 4.8 MB
Tags CPython 3.14 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
e2986b4f921d4a9cb0e1785d2cbc42d9a4b948a10d86d25224616df435bad4ee
BLAKE2b-256 checksum
How to use checksums
b85c1f3c16f2dc201f3ff8c42c4c08c85b2317436e1d8fff78ca458a678dda21
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL drone_planning-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 4.7 MB
Tags CPython 3.14 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
7869a510faad09384afaa3f1f3b5658fe58d6216eaed99a00bc75b0e5a4f60c3
BLAKE2b-256 checksum
How to use checksums
83754233fdae0300929662a7484353df4d453edd6dbfb2a55e7d10a6dd25eae1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp313-cp313-manylinux_2_34_x86_64.whl

Download URL drone_planning-0.1.0-cp313-cp313-manylinux_2_34_x86_64.whl
Size 4.8 MB
Tags CPython 3.13 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
399f1438ba0f3a120c8fe7cb37cdf1f86c0c006f909899640bf930dd7d69d445
BLAKE2b-256 checksum
How to use checksums
7473bfa623da834888ad8185a53a05f78e078142e036b37b535f5b88614b021c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL drone_planning-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 4.7 MB
Tags CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
cf9282231c1e281871826041e5f8b2e82c263e3eae88db295dee25acb06dd09e
BLAKE2b-256 checksum
How to use checksums
db67161a4e7b2a6121ec4b3e66b37f75a5b5945d728a04f9e6bb57fcc2f4bda2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl

Download URL drone_planning-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl
Size 4.8 MB
Tags CPython 3.12 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
9608c198b45bf96b93e58abde3a195da73be0da511d5a91b95c70dcc097ebebc
BLAKE2b-256 checksum
How to use checksums
03bc310bfe526bd6fa7af1fcfe28aea6b6cebbfbfee4c01afc41ed3ff225634e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL drone_planning-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 4.7 MB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
8408cd693f713a44ef8ced72c1f45daa94376a08733aad4a4ad36413ff96e759
BLAKE2b-256 checksum
How to use checksums
77767c38682811873ad830391bda972c777fade34ed474e7d045833cecff7307
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl

Download URL drone_planning-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl
Size 4.8 MB
Tags CPython 3.11 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
4393361927430fded0b1683063bfac5b0c5ce36481b9fd919aa8559130b9d9c6
BLAKE2b-256 checksum
How to use checksums
d3435ac2094a32303886b3b19eac696b745b38b74e1f1124a5bd215f56686426
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL drone_planning-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 4.7 MB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
1d0c4711264b319a01a9ee877a88b332a29ceba872a51adc155008c479854431
BLAKE2b-256 checksum
How to use checksums
a2dddf56dad5be0770b65599f2d922efebe94d84dd7dc8ba052dbac44577d934
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl

Download URL drone_planning-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl
Size 4.8 MB
Tags CPython 3.10 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
d902edd0e100ce33e00f9650390dd7456831d32f4245afa92cc0d701fa80440b
BLAKE2b-256 checksum
How to use checksums
ef369864514124c18557d05481d2991e3884f7d69f47dcbb3c16c559dc380cd7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / drone_planning-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL drone_planning-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 4.7 MB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
038fb4c379a6b806dff6124e6651632ea271419704e1ac46a8844bff399ad52c
BLAKE2b-256 checksum
How to use checksums
b29b382c07a02672057e53ba319773b569fcc6e663a85906869bf1bfd6a11030
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Security for drone-planning 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 10 files in this release have been uploaded with provenance metadata.

Select from 10 files

Attestation for drone_planning-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

10 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page