Flying Robots

Physical Hardware Experiments

Wolfgang Hönig

November 15, 2024

Grading

Grading Criteria

  • 20 (/ 100) points: simulation code and verbal discussion
    • 14 points code (written core math routines; correct dynamics; infrastructure code for simulation)
    • 3 points integration schema analysis
    • 3 points validation analysis

Assignment 1

  1. Show an example run of your code.
  2. Show your table/plot/results comparing two integration schemes.
  3. Show your validation of the dynamics.
  • What was difficult?
  • What was easy?

Notes and Lessons Learned

Open loop control for UAVs impossible!

  • Please use f32, not f64 (the real hardware has a single-precision FPU)
  • Avoid committing/pushing temporary files (e.g., target folder; use .gitignore)

Physical Flights

Crazyflie 2.1 Hardware Overview

  • Sensors:
    • Accelerometer / Gyroscope (BMI088)
    • Pressure sensor (BMP388)
  • Actuators:
    • 4 brushed motors with propellers
  • Compute:
    • Flight control: STM32 microcontroller (ARM Cortex-M4, 168 MHz, 192 kb RAM, 1 MB flash)
    • Communication: nRF51 (ARM Cortex-M0, 32 MHz, 16 kB RAM)
  • Extendable with add-on boards (decks)

Crazyflie 2.1 Hardware Schema

Crazyflie 2.1 Notable Extensions

Flow-Deck

  • Measures height (ToF up to 4m, VL53L1x)
  • Measures horizontal velocity (PMW3901)

uSD-deck

  • Can store binary flight logs

AI Deck

  • Camera (320x320)
  • 8+1 core RISC-V MCU (no FPU)

Crazyradio

  • nRF52840 with power amplifier and external antenna
    • Cortex-M4F (64MHz, 1MB flash, 256Kb RAM)
    • 2.4 GHz band
      • BlueTooth LE
      • proprietary Nordic modes (low latency)
  • USB interface

Crazyflie 2.1 Official Software

  • User facing libraries
    1. Phone applications (Android, iPhone)
    2. cflib: Python API to control robot(s) via Crazyradio
    3. cfclient: GUI for a single robot (Python, based on cflib)
  • Low-level (mostly C)
    1. STM32 Firmware: Primary flight control firmware
    2. AI deck examples
    3. NRF51 firmware, various Bootloaders, Crazyradio firmware

Flight Demo

  • Crazyflie with flow deck controlled in cfclient

Flight Control Firmware (CF)

Flight Control Firmware (PX4)

Flight Control Demo: Hello Rust

Install Rust for our target:

rustup target add thumbv7em-none-eabihf

Build official example:

git clone git@github.com:bitcraze/crazyflie-firmware.git
cd crazyflie-firmware
git submodule update --init
cd examples/app_hello_rs
make clean
make

Flash:

  1. Turn of the Crazyflie (short press power button)
  2. Put in bootloader (press power button for about 3 seconds)
  3. make cload

Flight Control Demo: Custom Controller

cd ../app_out_of_tree_controller
make clean
make

Rust Interoperability

Background

  • Projects are often written in several different languages

How can we cross the language barrier?

  • exec/fork (input/output via files)
  • Inter-process communication (MPI, shared memory, …)
  • Share the same Application Binary Interface (ABI) and link code
    • Most common example: C, C++ to be called from Python (e.g., numpy, pyTorch)

Calling Rust From C

  • Mark as extern C and disable name mangling

Export a function written in Rust

#[no_mangle]
pub extern "C" fn hello_from_rust() {
    println!("Hello from Rust!");
}

Call the function from C

extern void hello_from_rust();

int main(void) {
    hello_from_rust();
    return 0;
}

Calling C From Rust

  • Import a function (need to use Rust syntax and types!)

C function to import

int consolePutchar(int ch);

Rust code to call that function

extern "C" {
    pub fn consolePutchar(ch: i32) -> i32;
}

fn main() {
    consolePutchar(82);
}

Revisiting app_hello_rs

#![no_std]

use panic_halt as _;

extern "C" {
    pub fn vTaskDelay(ticks: u32);
    pub fn consolePutchar(ch: i32) -> i32;
}

fn console_print(msg: &str) {
    for c in msg.as_bytes() {
        unsafe{ consolePutchar(*c as i32); }
    }
}

#[no_mangle]
pub extern "C" fn appMain() -> i32 {
    console_print("Hello from Rust2!\n");

    loop {
        unsafe { vTaskDelay(1000); }
    }
}

Practical Considerations and Other Languages

Assignment 1.5 (Not Graded)

Instructions

  1. Make sure you can compile the firmware (instructions)
  2. Create your own “app” example for assignment1
  3. Add and compile your existing math library
    • Trigonometric functions are not in core; import sinf, cosf etc. from C
  4. Generate bindings for the controller using bindgen
    • The easiest (to not deal with errors) is to copy stabilizer_types.h and only include the structs that you need
  5. Test flight with stock software

Conclusion

Learned Today

  • Assignment 1 grading
  • Specifics of the hard- and software used for the class
  • Rust: Interoperability with other languages
  • Assignment 1.5 (as preparation for assignment 2)

Next Week

Controls lecture and Assignment 2.

Questions

?