See it live here
The Multirotor Rate Converter aims to provide multirotor enthusiasts with a tool to convert flight controller (FC) rates from one type to another.
Users can input their own rates or the rates of popular pilots to visually compare them. Additionally, the tool allows for the automatic conversion of these rates to a format of another flight controller software.
The rate calculations are derived directly from the Betaflight Configurator repository. This tool simply borrows their rate calculation file and gives it a new place to show off its curves.
There are two methods for rate calculation:
- API-Based Calculation: This method takes 10 data points from the source curve and uses non-linear least squares to(try to) find the best fit for the desired rate type.
- Local Gradient Descent: This method uses 500 data points and Mean Squared Error (MSE) to identify the best fit.
The on-device gradient descent calculation was developed as a proof of concept to potentially reduce monthly server costs. However, the API-based calculation is faster and the max rate is generally more accurate to the input.
- Implementation of different themes.
- Integration of a throttle slider.
- Implement tests for all functionalities.
- set colors for fc options
- betaflight -
rgb(238, 166, 0); - raceflight -
rgb(182, 25, 22); - kiss -
none? maybe light gray - actual -
rgb(25, 120, 178) - quick -
rgb(231, 33, 31)
- betaflight -
For local testing without docker, you can run the project and serve the web app using just python and flask
- python3.8
- virtual environment (
venv) - pip
if you dont have git installed you can visit this link to the repo and download the zip file by clicking code > download zip
git clone https://github.com/Marc-Anderson/multirotor-rate-converter.gitcd multirotor-rate-converterpython3 -m venv .venvsource .venv/bin/activatecd backend && pip3 install -r requirements.txt && cd ..Note: the Docker build and backend/requirements.txt reference ./core as a relative path, so it must be installed from inside backend/
python3 backend/wsgi.pyNote: to avoid issues with browser caching, use an incognito window or perform a hard refresh occasionally.
build an image and spin up a container containing the web app using docker compose
- linux, wsl2 in windows or multipass on macos
- docker
- non-root user
- git(recommeded)
if you dont have git installed you can visit this link to the repo and download the zip file by clicking code > download zip
git clone https://github.com/Marc-Anderson/multirotor-rate-converter.gitcd multirotor-rate-convertercp .env.example .envthe defaults work as-is for local testing, no editing needed
docker compose up -d --builddocker compose down- linux vps
- docker
- ufw
- fail2ban (recommended)
- non-root user
- ssh public key for user
- a domain name with dns already pointed at this host's ip address
caddy (the reverse proxy/static file server in front of the app) automatically requests and renews a let's encrypt certificate for DOC_DOMAIN the first time it starts, as long as that domain's dns points at this server and ports 80/443 are reachable from the internet. there's nothing to download, upload, or renew by hand.
Click To Expand: overview of server config
this guide isnt going to cover this entirely but here is a brief overview with commands
# 1. create a new droplet on digitalocean
# 2. select the marketplace images > docker
# 3. choose the smallest possible vps
# 4. log into the console as root from the website ui
# 5. continue with the below steps
# define a non-root username and ssh public key
# default password will be your username
USERNAME=docker_user
SSH_KEY_NAME="computer"
SSH_PUBLIC_KEY=""
# EXAMPLE_SSH_PUBLIC_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZzHpY7r6bRpN2u/9eLsPYkbZK8ZwCff9yM7qXzjV5b fakeuser@example.com"
TEMP_PASSWORD=$USERNAME
# make sure you provided a public key
if [ -z "$SSH_PUBLIC_KEY" ]; then
echo "Error: SSH_PUBLIC_KEY is empty."
exit 1
fi
# update package list and install required tools
sudo apt-get update && sudo apt-get install -y ufw git fail2ban
# disable firewall
sudo ufw disable
# reset firewall to remove all rules
sudo echo "y" | sudo ufw reset
# allow but limit ssh
sudo ufw limit 22/tcp
# re-enable firewall
sudo echo "y" | sudo ufw enable
# confirm firewall status for JUST ssh
sudo ufw status
# create user and add them to the sudo group
useradd --create-home --shell /bin/bash --groups sudo "${USERNAME}"
# add the user to the docker group if it exists
if command -v docker >/dev/null 2>&1; then usermod -aG docker "${USERNAME}"; fi
# give the user a default password
echo "${USERNAME}:${TEMP_PASSWORD}" | chpasswd
# force password reset on next login
# password defaults to username
chage --lastday 0 "${USERNAME}"
# create ssh directory for new user
home_directory="$(eval echo ~${USERNAME})"
mkdir --parents "${home_directory}/.ssh"
# add specified public key to authorized keys for new user with the key description as a comment
echo "# ${SSH_KEY_NAME}" >> "${home_directory}/.ssh/authorized_keys"
echo $SSH_PUBLIC_KEY >> "${home_directory}/.ssh/authorized_keys"
# update the permissions of the ssh folder and files
chmod 0700 "${home_directory}/.ssh"
chmod 0600 "${home_directory}/.ssh/authorized_keys"
chown --recursive "${USERNAME}":"${USERNAME}" "${home_directory}/.ssh"
# switch to the new user
sudo su - $USERNAMEif you dont have git installed you can visit this link to the repo and download the zip file by clicking code > download zip
git clone https://github.com/Marc-Anderson/multirotor-rate-converter.gitcd multirotor-rate-converter3. point your domain's dns at this server, then copy the example env file and set DOC_DOMAIN and HTTP_PORT (and optionally SSL_EMAIL)
cp .env.example .envedit .env by hand - set DOC_DOMAIN to your domain and uncomment HTTP_PORT=80 - or replace the variables below and run this command
domain_name=example.com
ssl_email_address=webmaster@example.com
sed -i -e "s/^# DOC_DOMAIN=.*/DOC_DOMAIN=$domain_name/" -e "s/^# SSL_EMAIL=.*/SSL_EMAIL=$ssl_email_address/" -e "s/^# HTTP_PORT=.*/HTTP_PORT=80/" .envsudo systemctl enable fail2ban
sudo systemctl start fail2bansudo ufw allow 80/tcp && sudo ufw allow 443/tcp
sudo ufw enablehostname -I
dig $domain_namedocker compose up -d --build8. visit your domain over https - caddy requests the certificate on first access, no extra steps needed
docker compose downtest cases include all valid rate conversions on the website between october 2024 and april 2025.
pip3 install requestscd backend/core
python3 -m unittest tests/test_000_bulk.py -f
# it will take a second to get going on the first run
# if you want to run all tests in spite of failures you can remove the -f
# `python3 -m unittest tests/test_000_bulk.py `- check the number of failures, all tests should pass
- every 5000 tests, the system will try a random set of values
- at the end you can review the results file in
./tests/RESULTS.txt - check the error rate compared to the current
testresults
- the
testresult is the known values of the existing best solution - upgrading to python3.13 we lost
153.94. i hope to resolve this in the future