cu-flight-controller 0.15.0

This is a basic quadcopter Flight Controller implemented end to end using Copper components
Documentation
ROOT := `git rev-parse --show-toplevel`

# Run the Bevy + Copper simulation loop.
default: sim

# Render copperconfig.ron from the current working directory.
dag mission="":
  #!/usr/bin/env bash
  set -euo pipefail

  invocation_dir="{{invocation_directory()}}"
  cfg_path="${invocation_dir}/copperconfig.ron"
  if [[ ! -f "$cfg_path" ]]; then
    echo "No copperconfig.ron found in ${invocation_dir}" >&2
    exit 1
  fi

  cd "{{ROOT}}"
  mission_value="{{mission}}"
  if [[ -n "$mission_value" ]]; then
    cargo run -p cu29-runtime --bin cu29-rendercfg -- --mission "$mission_value" --open "$cfg_path"
  else
    cargo run -p cu29-runtime --bin cu29-rendercfg -- --open "$cfg_path"
  fi

# A quick test to see if the sim can pick up your RC.
rc:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  cargo run -p cu-flight-controller --no-default-features --features sim --bin rc-tester

# Run the Bevy + Copper simulation loop.
sim:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  cargo run -p cu-flight-controller --no-default-features --features sim --bin quad-sim

# Run the Bevy + Copper simulation loop with cu_bevymon embedded in the window.
bevy:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  cargo run -p cu-flight-controller --no-default-features --features bevymon --bin quad-bevymon

# Download the local scene assets needed by the browser BevyMon app.
prepare-assets:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{invocation_directory()}}"
  mkdir -p assets
  if [[ ! -f "assets/quadcopter.glb" ]]; then
    echo "Downloading quadcopter.glb..."
    curl --fail --location --silent --show-error --output "assets/quadcopter.glb" "https://cdn.copper-robotics.com/quadcopter.glb"
  fi
  if [[ ! -f "assets/city-fixed.glb" ]]; then
    echo "Downloading city-fixed.glb..."
    curl --fail --location --silent --show-error --output "assets/city-fixed.glb" "https://cdn.copper-robotics.com/city-fixed.glb"
  fi
  if [[ ! -f "assets/skybox.ktx2" ]]; then
    echo "Downloading skybox.ktx2..."
    curl --fail --location --silent --show-error --output "assets/skybox.ktx2" "https://cdn.copper-robotics.com/skybox.ktx2"
  fi
  if [[ ! -f "assets/specular_map.ktx2" ]]; then
    echo "Downloading specular_map.ktx2..."
    curl --fail --location --silent --show-error --output "assets/specular_map.ktx2" "https://cdn.copper-robotics.com/specular_map.ktx2"
  fi

# Serve the BevyMon flight controller sim in the browser.
web:
  #!/usr/bin/env bash
  set -euo pipefail
  if ! command -v trunk >/dev/null 2>&1; then
    echo "Missing trunk. Install with: cargo install --locked trunk" >&2
    exit 1
  fi
  cd "{{invocation_directory()}}"
  just prepare-assets
  trunk serve --open

# Build a static browser bundle into dist/flight-controller with hashed asset filenames.
web-dist:
  #!/usr/bin/env bash
  set -euo pipefail
  if ! command -v trunk >/dev/null 2>&1; then
    echo "Missing trunk. Install with: cargo install --locked trunk" >&2
    exit 1
  fi
  cd "{{invocation_directory()}}"
  just prepare-assets
  rm -rf dist/flight-controller
  trunk build --release --public-url ./ --dist dist/flight-controller
  echo "Static web bundle written to ${PWD}/dist/flight-controller"

# Extract CopperLists from a log file (JSON export).
logreader log="logs/flight_controller_sim.copper":
  #!/usr/bin/env bash
  set -euo pipefail
  invocation_dir="{{invocation_directory()}}"
  log="{{log}}"
  if [[ "$log" != /* ]]; then
    log="${invocation_dir}/${log}"
  fi
  RUST_BACKTRACE=1 cargo run -p cu-flight-controller --no-default-features --features logreader --bin quad-logreader -- "$log" extract-copperlists --export-format json

# Build the cu_flight_controller Python extension module.
py-build:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  cargo rustc -p cu-flight-controller --no-default-features --features python-bindings --lib --crate-type cdylib

# Python example reading the log.
py log="logs/flight_controller_sim.copper": py-build
  #!/usr/bin/env bash
  set -euo pipefail
  invocation_dir="{{invocation_directory()}}"
  log="{{log}}"
  if [[ "$log" != /* ]]; then
    log="${invocation_dir}/${log}"
  fi
  cd "{{ROOT}}"
  cargo rustc -p cu-flight-controller --no-default-features --features python-bindings --lib --crate-type cdylib
  python3 "${invocation_dir}/python/print_gnss_from_log.py" "$log"

# Print GNSS coordinates from a Copper log via the Python extension.
py-gnss log="logs/flight_controller_sim.copper":
  #!/usr/bin/env bash
  set -euo pipefail
  invocation_dir="{{invocation_directory()}}"
  log="{{log}}"
  if [[ "$log" != /* ]]; then
    log="${invocation_dir}/${log}"
  fi
  cd "{{ROOT}}"
  cargo rustc -p cu-flight-controller --no-default-features --features python-bindings --lib --crate-type cdylib
  python3 "${invocation_dir}/python/print_gnss_from_log.py" "$log"
# Run log reader fsck against a log file.
fsck log="logs/flight_controller_sim.copper":
  #!/usr/bin/env bash
  set -euo pipefail
  invocation_dir="{{invocation_directory()}}"
  log="{{log}}"
  if [[ "$log" != /* ]]; then
    log="${invocation_dir}/${log}"
  fi
  RUST_BACKTRACE=1 cargo run -p cu-flight-controller --no-default-features --features logreader --bin quad-logreader -- "$log" fsck

# Extract text logs with a specified log index directory.
textlogs log="logs/embedded.copper" index="../../target/debug/cu29_log_index":
  #!/usr/bin/env bash
  set -euo pipefail
  invocation_dir="{{invocation_directory()}}"
  log="{{log}}"
  index="{{index}}"
  if [[ "$log" != /* ]]; then
    log="${invocation_dir}/${log}"
  fi
  if [[ "$index" != /* ]]; then
    index="${invocation_dir}/${index}"
  fi
  [[ -e "$index" ]] || { echo "log index not found: $index" >&2; exit 1; }
  RUST_BACKTRACE=1 cargo run -p cu-flight-controller --no-default-features --features logreader --bin quad-logreader -- "$log" extract-text-log "$index"

# Build and run firmware with textlogs enabled (release profile).
fw:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  cargo run --release --config examples/cu_flight_controller/.cargo/config-firmware.toml --no-default-features --features firmware,textlogs -p cu-flight-controller --bin quad

# Release release. With no textlogs.
fwr:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  cargo run --profile screaming --config examples/cu_flight_controller/.cargo/config-firmware.toml --no-default-features --features firmware -p cu-flight-controller --bin quad

# Debug (it won't be fast enough to run be at least you van debug the bringup).
fwd:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  cargo run --config examples/cu_flight_controller/.cargo/config-firmware.toml --no-default-features --features firmware,log-level-debug -p cu-flight-controller --bin quad

# Attach to the already-flashed target without rebuilding or flashing.
attach:
  #!/usr/bin/env bash
  set -euo pipefail
  cd "{{ROOT}}"
  probe-rs attach --chip STM32H743VITx --protocol swd target/thumbv7em-none-eabihf/release/quad