mirror of
https://github.com/okalachev/flix.git
synced 2026-08-16 00:38:56 +00:00
Compare commits
155
Commits
6064ee18f3
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d825652a71 | ||
|
|
37f267ecc9 | ||
|
|
3450932dce | ||
|
|
149c891cfc | ||
|
|
0512f5ce68 | ||
|
|
f12b239af9 | ||
|
|
0a377cfe6f | ||
|
|
fd8bf03cc7 | ||
|
|
3ea680605a | ||
|
|
5edac09473 | ||
|
|
7312aeff32 | ||
|
|
d65c5c0eb1 | ||
|
|
76456b778b | ||
|
|
f79c444f07 | ||
|
|
2a96f4795d | ||
|
|
6c55ab3625 | ||
|
|
97edb8e65b | ||
|
|
bfeee7a00a | ||
|
|
3f4577bb2c | ||
|
|
070eb8a0de | ||
|
|
aee43c6548 | ||
|
|
8e276bde38 | ||
|
|
a5991930d1 | ||
|
|
406f7a4af5 | ||
|
|
5ee6d91440 | ||
|
|
38925d7885 | ||
|
|
5c81181221 | ||
|
|
fd249fcaa6 | ||
|
|
8917849711 | ||
|
|
1cdc7a8641 | ||
|
|
d64bf24c6d | ||
|
|
fabd5e072d | ||
|
|
1ae85ff118 | ||
|
|
26a0dd65be | ||
|
|
9d439afd80 | ||
|
|
64b21a3a6b | ||
|
|
545eed8944 | ||
|
|
518abf1555 | ||
|
|
17df1c5396 | ||
|
|
8e2ffd7c69 | ||
|
|
52b74afba6 | ||
|
|
0ca2473655 | ||
|
|
b4c2fe3988 | ||
|
|
e51b47b798 | ||
|
|
71abe1bcdb | ||
|
|
0f2e384ce6 | ||
|
|
5e153a210d | ||
|
|
9d47bcb82e | ||
|
|
1fafc27b39 | ||
|
|
faca48ced3 | ||
|
|
a5dbd2c829 | ||
|
|
59f9528d34 | ||
|
|
607b2ff0b7 | ||
|
|
22c06f76c4 | ||
|
|
488ceb3004 | ||
|
|
b83c9b3845 | ||
|
|
2f4b1423e6 | ||
|
|
4e32414dae | ||
|
|
a294883dea | ||
|
|
cdfba72a0b | ||
|
|
18e81720e0 | ||
|
|
91173d06c9 | ||
|
|
fdcc9533b3 | ||
|
|
bd2b1bd5de | ||
|
|
4530c05b5c | ||
|
|
3816ae376f | ||
|
|
72a72fde80 | ||
|
|
e53051a349 | ||
|
|
f8a9f1f838 | ||
|
|
76af83fc88 | ||
|
|
dd176180a7 | ||
|
|
48c33c7050 | ||
|
|
35e94f6ea6 | ||
|
|
1f48e379e3 | ||
|
|
ee3c6999ab | ||
|
|
34c6993842 | ||
|
|
b62f2f9427 | ||
|
|
7dfef17165 | ||
|
|
8c8046676b | ||
|
|
702ec9792e | ||
|
|
06e2047097 | ||
|
|
87480476c2 | ||
|
|
68271c508c | ||
|
|
e81e84e7fc | ||
|
|
5f1a938d4f | ||
|
|
bd270db493 | ||
|
|
dbf24ea611 | ||
|
|
08683d696d | ||
|
|
9ca6841558 | ||
|
|
28da2d3c8e | ||
|
|
c6632ae6e4 | ||
|
|
35ca754583 | ||
|
|
2ccda03573 | ||
|
|
485a39e740 | ||
|
|
9bffe5b52f | ||
|
|
d6a79d6c66 | ||
|
|
350a82bfed | ||
|
|
6e439859bc | ||
|
|
835b2243e8 | ||
|
|
ed4e2d87d1 | ||
|
|
51cd5fc691 | ||
|
|
d8591ea2a9 | ||
|
|
c434107eaf | ||
|
|
814427dbfd | ||
|
|
0730ceeffa | ||
|
|
a687303062 | ||
|
|
b2daf2587f | ||
|
|
a8c25d8ac0 | ||
|
|
3e49d41986 | ||
|
|
67430c7aac | ||
|
|
3631743a29 | ||
|
|
3dde380bb7 | ||
|
|
377b21429b | ||
|
|
1ac443d6f8 | ||
|
|
964c0f7bc1 | ||
|
|
40bdaacedb | ||
|
|
7d74f3d5cd | ||
|
|
9fd35ba361 | ||
|
|
ca50f75576 | ||
|
|
e47a31f981 | ||
|
|
7ad3022798 | ||
|
|
5b654e4d8e | ||
|
|
cf10ec6161 | ||
|
|
6d01cd2e79 | ||
|
|
0abb18c616 | ||
|
|
30326a5662 | ||
|
|
dd3575174b | ||
|
|
c0f3301da4 | ||
|
|
a6bad3a69b | ||
|
|
9a9bd07251 | ||
|
|
28f5855a57 | ||
|
|
7e24ee30f7 | ||
|
|
2a8faf5759 | ||
|
|
f4e58a652a | ||
|
|
6c46328da1 | ||
|
|
c8e5e08b03 | ||
|
|
a5e3dfcf69 | ||
|
|
d6e8be0c05 | ||
|
|
68d16855df | ||
|
|
0547ea548b | ||
|
|
c02dba6812 | ||
|
|
f1dc4a0400 | ||
|
|
158827ac55 | ||
|
|
36ca30c3e4 | ||
|
|
48711b55e1 | ||
|
|
4d583185a9 | ||
|
|
d757ffa853 | ||
|
|
5352386486 | ||
|
|
9b5872740f | ||
|
|
31dbdaf241 | ||
|
|
f4b56262b1 | ||
|
|
49039f752d | ||
|
|
348721acc9 | ||
|
|
774144c430 | ||
|
|
0e6651ab82 |
+18
-11
@@ -13,7 +13,7 @@ jobs:
|
||||
env:
|
||||
ARDUINO_SKETCH_ALWAYS_EXPORT_BINARIES: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install Arduino CLI
|
||||
run: curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
|
||||
- name: Build firmware for ESP32
|
||||
@@ -28,22 +28,20 @@ jobs:
|
||||
run: make BOARD=esp32:esp32:esp32s3:CDCOnBoot=cdc,PSRAM=opi EXTRA=--output-dir=flix/build/esp32.esp32.esp32s3.opi
|
||||
- name: Build firmware for Flix2
|
||||
run: make BOARD=esp32:esp32:esp32s3:FlashSize=4M,CDCOnBoot=cdc,PSRAM=opi EXTRA='--build-property "compiler.cpp.extra_flags=-DFLIX2" --output-dir=flix/build/esp32.esp32.flix2'
|
||||
- name: Build firmware for STM32F4
|
||||
run: |
|
||||
arduino-cli core install STMicroelectronics:stm32 --additional-urls https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
|
||||
make BOARD=STMicroelectronics:stm32:GenF4
|
||||
- name: Upload binaries
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: firmware-binary
|
||||
path: flix/build
|
||||
- name: Build espnow-proxy
|
||||
run: arduino-cli compile --fqbn esp32:esp32:esp32 tools/espnow-proxy
|
||||
- name: Check c_cpp_properties.json
|
||||
run: tools/check_c_cpp_properties.py
|
||||
|
||||
build_macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install Arduino CLI
|
||||
run: brew install arduino-cli
|
||||
- name: Build firmware
|
||||
@@ -54,7 +52,7 @@ jobs:
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install Arduino CLI
|
||||
run: choco install arduino-cli
|
||||
- name: Install Make
|
||||
@@ -75,7 +73,7 @@ jobs:
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y curl wget build-essential cmake g++ pkg-config gnupg2 lsb-release sudo
|
||||
- name: Install Arduino CLI
|
||||
run: curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install Gazebo
|
||||
run: |
|
||||
sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
|
||||
@@ -86,7 +84,16 @@ jobs:
|
||||
run: sudo apt-get install -y libsdl2-dev
|
||||
- name: Build simulator
|
||||
run: make build_simulator
|
||||
- uses: actions/upload-artifact@v4
|
||||
- name: Run simulator
|
||||
env:
|
||||
GAZEBO_MODEL_PATH: ${{ github.workspace }}/gazebo/models
|
||||
GAZEBO_PLUGIN_PATH: ${{ github.workspace }}/gazebo/build
|
||||
run: |
|
||||
OUT=$(timeout -k 10s 120s gzserver --verbose gazebo/flix.world 2>&1 | tee /dev/stderr)
|
||||
if echo "$OUT" | grep -Pq "\[Err\](?! \[RenderEngine)"; then
|
||||
exit 1
|
||||
fi
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: gazebo-plugin-binary
|
||||
path: gazebo/build/*.so
|
||||
@@ -98,7 +105,7 @@ jobs:
|
||||
steps:
|
||||
- name: Install Arduino CLI
|
||||
run: brew install arduino-cli
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Clean up python binaries # Workaround for https://github.com/actions/setup-python/issues/577
|
||||
run: |
|
||||
rm -f /usr/local/bin/2to3*
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
markdownlint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install markdownlint
|
||||
run: npm install -g markdownlint-cli2
|
||||
- name: Run markdownlint
|
||||
@@ -25,13 +25,16 @@ jobs:
|
||||
build_book:
|
||||
runs-on: ubuntu-latest
|
||||
needs: markdownlint
|
||||
env:
|
||||
BINARIES: ${{ github.event_name == 'push' && (github.ref_name == 'master' || github.ref_name == 'dev') && github.repository == 'okalachev/flix' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install mdBook
|
||||
run: cargo install mdbook --vers 0.4.43 --locked
|
||||
- name: Build book
|
||||
run: cd docs && mdbook build
|
||||
- name: Wait for Build to complete
|
||||
if: ${{ env.BINARIES }}
|
||||
uses: lewagon/wait-on-check-action@v1.9.1
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
@@ -39,6 +42,7 @@ jobs:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 30
|
||||
- name: Find firmware binaries
|
||||
if: ${{ env.BINARIES }}
|
||||
id: build_run
|
||||
run: |
|
||||
RUN_ID=$(gh api "repos/${{ github.repository }}/actions/workflows/build.yml/runs?head_sha=${{ github.sha }}&per_page=1" --jq '.workflow_runs[0].id')
|
||||
@@ -46,7 +50,8 @@ jobs:
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Download firmware binaries
|
||||
uses: actions/download-artifact@v4
|
||||
if: ${{ env.BINARIES }}
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
repository: ${{ github.repository }}
|
||||
@@ -54,6 +59,7 @@ jobs:
|
||||
name: firmware-binary
|
||||
path: docs/build
|
||||
- name: Create shortcuts for firmware binaries
|
||||
if: ${{ env.BINARIES }}
|
||||
working-directory: docs/build
|
||||
run: |
|
||||
for FQBN in esp32.esp32.*; do
|
||||
@@ -64,12 +70,12 @@ jobs:
|
||||
ln -s "$FQBN/flix.ino.bootloader.bin" "flix.$BOARD.bootloader.bin"
|
||||
done
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
uses: actions/upload-pages-artifact@v5
|
||||
with:
|
||||
path: docs/build
|
||||
|
||||
deploy:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
if: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: true
|
||||
@@ -81,4 +87,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
uses: actions/deploy-pages@v5
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
csv_to_ulog:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Build csv_to_ulog
|
||||
run: cd tools/csv_to_ulog && mkdir build && cd build && cmake .. && make
|
||||
- name: Test csv_to_ulog
|
||||
@@ -22,13 +22,13 @@ jobs:
|
||||
pyflix:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install Python build tools
|
||||
run: pip install build
|
||||
- name: Build pyflix
|
||||
run: python3 -m build tools
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: pyflix
|
||||
path: |
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
python_tools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install Python dependencies
|
||||
run: pip install -r tools/requirements.txt
|
||||
- name: Test csv_to_mcap tool
|
||||
@@ -46,3 +46,23 @@ jobs:
|
||||
echo -e "t,x,y,z\n0,1,2,3\n1,4,5,6" > log.csv
|
||||
./csv_to_mcap.py log.csv
|
||||
test $(stat -c %s log.mcap) -eq 883
|
||||
sloc:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- run: sudo apt-get install -y cloc jq
|
||||
- name: Print source lines of code
|
||||
run: cloc --by-file-by-lang flix
|
||||
- name: Checkout previous revision
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
|
||||
path: prev
|
||||
- name: Annotate total source lines
|
||||
run: |
|
||||
SLOC_CURR=$(cloc flix --json | jq -r '.SUM.code')
|
||||
SLOC_PREV=$(cloc prev/flix --json | jq -r '.SUM.code')
|
||||
DIFF=$(printf '%+d' "$((SLOC_CURR - SLOC_PREV))")
|
||||
echo "* Current SLOC: $SLOC_CURR" >> $GITHUB_STEP_SUMMARY
|
||||
echo "* Previous SLOC: $SLOC_PREV" >> $GITHUB_STEP_SUMMARY
|
||||
echo "* Diff: $DIFF" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
@@ -4,10 +4,10 @@ PORT := $(strip $(wildcard /dev/serial/by-id/usb-Silicon_Labs_CP21* /dev/serial/
|
||||
export ARDUINO_NETWORK_CONNECTION_TIMEOUT := 1h
|
||||
|
||||
build: .core .libs
|
||||
arduino-cli compile --fqbn $(BOARD) --build-property "build.core_debug_level=1" flix $(EXTRA)
|
||||
arduino-cli compile flix --fqbn $(BOARD) --build-property "build.core_debug_level=1" $(EXTRA)
|
||||
|
||||
upload: build
|
||||
arduino-cli upload --fqbn $(BOARD) -p "$(PORT)" flix
|
||||
arduino-cli upload flix --fqbn $(BOARD) -p "$(PORT)"
|
||||
|
||||
erase:
|
||||
arduino-cli burn-bootloader --fqbn $(BOARD) -p "$(PORT)" -P esptool
|
||||
@@ -27,8 +27,8 @@ libs .libs:
|
||||
touch .libs
|
||||
|
||||
upload_proxy: .core .libs
|
||||
arduino-cli compile --fqbn $(BOARD) tools/espnow-proxy
|
||||
arduino-cli upload --fqbn $(BOARD) -p "$(PORT)" tools/espnow-proxy
|
||||
arduino-cli compile tools/espnow-proxy --fqbn $(BOARD)
|
||||
arduino-cli upload tools/espnow-proxy --fqbn $(BOARD) -p "$(PORT)"
|
||||
|
||||
gazebo/build cmake: gazebo/CMakeLists.txt
|
||||
mkdir -p gazebo/build
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
* [`vector.h`](https://github.com/okalachev/flix/blob/master/flix/vector.h), [`quaternion.h`](https://github.com/okalachev/flix/blob/master/flix/quaternion.h) — библиотеки векторов и кватернионов.
|
||||
* [`pid.h`](https://github.com/okalachev/flix/blob/master/flix/pid.h) — ПИД-регулятор.
|
||||
* [`lpf.h`](https://github.com/okalachev/flix/blob/master/flix/lpf.h) — фильтр нижних частот.
|
||||
* [`filter.h`](https://github.com/okalachev/flix/blob/master/flix/filter.h) — фильтр нижних частот.
|
||||
|
||||
### Подсистема управления
|
||||
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ Utility files:
|
||||
|
||||
* [`vector.h`](../flix/vector.h), [`quaternion.h`](../flix/quaternion.h) — vector and quaternion libraries.
|
||||
* [`pid.h`](../flix/pid.h) — generic PID controller.
|
||||
* [`lpf.h`](../flix/lpf.h) — generic low-pass filter.
|
||||
* [`filter.h`](../flix/filter.h) — generic low-pass filter.
|
||||
|
||||
### Control subsystem
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#include "pid.h"
|
||||
#include "vector.h"
|
||||
#include "util.h"
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
|
||||
extern const int MOTOR_REAR_LEFT, MOTOR_REAR_RIGHT, MOTOR_FRONT_RIGHT, MOTOR_FRONT_LEFT;
|
||||
extern const int RAW, ACRO, STAB, AUTO;
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#include "vector.h"
|
||||
#include "quaternion.h"
|
||||
#include "pid.h"
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
#include "util.h"
|
||||
|
||||
const int RAW = 0, ACRO = 1, STAB = 2, AUTO = 3; // flight modes
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "quaternion.h"
|
||||
#include "vector.h"
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
#include "util.h"
|
||||
|
||||
Vector rates; // estimated angular rates, rad/s
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#include <Wire.h>
|
||||
#include <FlixPeriph.h>
|
||||
#include "vector.h"
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
#include "util.h"
|
||||
|
||||
IMU *imu;
|
||||
|
||||
@@ -19,27 +19,18 @@ const int MOTOR_REAR_LEFT = 0, MOTOR_REAR_RIGHT = 1, MOTOR_FRONT_RIGHT = 2, MOTO
|
||||
void setupMotors() {
|
||||
print("Setup motors\n");
|
||||
// Configure pins
|
||||
#ifdef ESP32
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (motorPins[i] < 0) continue; // skip unassigned motors
|
||||
ledcAttach(motorPins[i], pwmFrequency, pwmResolution);
|
||||
pwmFrequency = ledcChangeFrequency(motorPins[i], pwmFrequency, pwmResolution); // when reconfiguring
|
||||
}
|
||||
#else
|
||||
analogWriteResolution(pwmResolution);
|
||||
analogWriteFrequency(pwmFrequency);
|
||||
#endif
|
||||
sendMotors();
|
||||
}
|
||||
|
||||
void sendMotors() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (motorPins[i] < 0) continue; // skip unassigned motors
|
||||
#ifdef ESP32
|
||||
ledcWrite(motorPins[i], getDutyCycle(motors[i]));
|
||||
#else
|
||||
analogWrite(motorPins[i], getDutyCycle(motors[i]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
|
||||
// Parameters storage in flash memory
|
||||
|
||||
#include "prefs.h"
|
||||
#include <Preferences.h>
|
||||
#include "util.h"
|
||||
|
||||
extern int channelZero[16], channelMax[16];
|
||||
@@ -22,7 +22,7 @@ struct Parameter {
|
||||
const char *name; // max length is 15
|
||||
bool integer;
|
||||
union { float *f; int *i; }; // pointer to the variable
|
||||
float inital; // default value
|
||||
float initial; // default value
|
||||
float cache; // what's stored in flash
|
||||
void (*callback)(); // called after parameter change
|
||||
Parameter(const char *name, float *variable, void (*callback)() = nullptr) : name(name), integer(false), f(variable), callback(callback) {};
|
||||
@@ -150,7 +150,7 @@ void setupParameters() {
|
||||
storage.begin("flix");
|
||||
// Read parameters from storage
|
||||
for (auto ¶meter : parameters) {
|
||||
parameter.inital = parameter.getValue();
|
||||
parameter.initial = parameter.getValue();
|
||||
if (storage.isKey(parameter.name)) {
|
||||
parameter.setValue(storage.getFloat(parameter.name));
|
||||
}
|
||||
@@ -211,10 +211,10 @@ void printParameters(const char *filter) {
|
||||
for (auto ¶meter : parameters) {
|
||||
if (strncasecmp(parameter.name, filter, strlen(filter))) continue;
|
||||
|
||||
if (floatEquals(parameter.getValue(), parameter.inital)) { // parameter changed
|
||||
if (floatEquals(parameter.getValue(), parameter.initial)) { // parameter changed
|
||||
print("%-15s %-13g\n", parameter.name, parameter.getValue());
|
||||
} else {
|
||||
print("%-15s %-13g [%g]\n", parameter.name, parameter.getValue(), parameter.inital);
|
||||
print("%-15s %-13g [%g]\n", parameter.name, parameter.getValue(), parameter.initial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
|
||||
class PID {
|
||||
public:
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
|
||||
LowPassFilter<float> lpf; // low pass filter for derivative term
|
||||
|
||||
PID(float p, float i = 0, float d = 0, float windup = 0, float dAlpha = 1, float dtMax = 0.1) :
|
||||
PID(float p, float i = 0, float d = 0, float windup = INFINITY, float dAlpha = 1, float dtMax = 0.1) :
|
||||
p(p), i(i), d(d), windup(windup), lpf(dAlpha), dtMax(dtMax) {}
|
||||
|
||||
float update(float error) {
|
||||
|
||||
+1
-5
@@ -3,11 +3,9 @@
|
||||
|
||||
// Power management
|
||||
|
||||
#ifdef ESP32
|
||||
#include <soc/soc.h>
|
||||
#include <soc/rtc_cntl_reg.h>
|
||||
#endif
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
#include "util.h"
|
||||
|
||||
float voltage = NAN;
|
||||
@@ -16,9 +14,7 @@ int voltagePin = -1;
|
||||
float voltageScale = 2;
|
||||
|
||||
void setupPower() {
|
||||
#ifdef ESP32
|
||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ENA); // disable reset on low voltage
|
||||
#endif
|
||||
if (digitalPinToAnalogChannel(voltagePin) == -1) voltagePin = -1; // test ADC pin
|
||||
}
|
||||
|
||||
|
||||
-283
@@ -1,283 +0,0 @@
|
||||
#ifdef ESP32
|
||||
#include <Preferences.h>
|
||||
#else
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <EEPROM.h>
|
||||
#include <string.h>
|
||||
|
||||
class Preferences {
|
||||
public:
|
||||
Preferences() = default;
|
||||
~Preferences() = default;
|
||||
|
||||
bool begin(const char *name, bool readOnly = false, const char *partition_label = NULL) {
|
||||
(void)name;
|
||||
(void)readOnly;
|
||||
(void)partition_label;
|
||||
load();
|
||||
started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void end() {
|
||||
started = false;
|
||||
}
|
||||
|
||||
bool clear() {
|
||||
if (!started) return false;
|
||||
for (auto &entry : entries) {
|
||||
entry = Entry();
|
||||
}
|
||||
return save();
|
||||
}
|
||||
|
||||
size_t putFloat(const char *key, float value) {
|
||||
if (!started) return 0;
|
||||
int index = ensureKey(key);
|
||||
if (index < 0) return 0;
|
||||
entries[index].hasFloat = true;
|
||||
entries[index].hasString = false;
|
||||
entries[index].stringValue = "";
|
||||
entries[index].floatValue = value;
|
||||
if (!save()) return 0;
|
||||
return sizeof(float);
|
||||
}
|
||||
|
||||
float getFloat(const char *key, float defaultValue = NAN) {
|
||||
if (!started) return defaultValue;
|
||||
int index = findKey(key);
|
||||
if (index < 0 || !entries[index].hasFloat) return defaultValue;
|
||||
return entries[index].floatValue;
|
||||
}
|
||||
|
||||
size_t putString(const char *key, const char *value) {
|
||||
if (!started) return 0;
|
||||
int index = ensureKey(key);
|
||||
if (index < 0) return 0;
|
||||
if (!value) value = "";
|
||||
if (strlen(value) > MAX_STRING_LEN) return 0;
|
||||
|
||||
entries[index].hasString = true;
|
||||
entries[index].hasFloat = false;
|
||||
entries[index].stringValue = value;
|
||||
if (!save()) return 0;
|
||||
return entries[index].stringValue.length();
|
||||
}
|
||||
|
||||
size_t putString(const char *key, String value) {
|
||||
return putString(key, value.c_str());
|
||||
}
|
||||
|
||||
String getString(const char *key, String defaultValue = String()) {
|
||||
if (!started) return defaultValue;
|
||||
int index = findKey(key);
|
||||
if (index < 0 || !entries[index].hasString) return defaultValue;
|
||||
return entries[index].stringValue;
|
||||
}
|
||||
|
||||
bool isKey(const char *key) {
|
||||
if (!started) return false;
|
||||
return findKey(key) >= 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static const int MAX_ENTRIES = 128;
|
||||
static const int MAX_KEY_LEN = 15;
|
||||
static const int MAX_STRING_LEN = 95;
|
||||
static const uint32_t MAGIC = 0x46504B56; // "VKPF"
|
||||
static const uint8_t VERSION = 1;
|
||||
static const uint8_t TYPE_FLOAT = 1;
|
||||
static const uint8_t TYPE_STRING = 2;
|
||||
static const int STORAGE_SIZE = 4096;
|
||||
|
||||
struct Entry {
|
||||
bool used = false;
|
||||
char key[MAX_KEY_LEN + 1] = {};
|
||||
bool hasFloat = false;
|
||||
float floatValue = NAN;
|
||||
bool hasString = false;
|
||||
String stringValue;
|
||||
};
|
||||
|
||||
bool started = false;
|
||||
Entry entries[MAX_ENTRIES];
|
||||
|
||||
static void writeU16(uint8_t *dst, uint16_t value) {
|
||||
dst[0] = static_cast<uint8_t>(value & 0xFF);
|
||||
dst[1] = static_cast<uint8_t>((value >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
static void writeU32(uint8_t *dst, uint32_t value) {
|
||||
dst[0] = static_cast<uint8_t>(value & 0xFF);
|
||||
dst[1] = static_cast<uint8_t>((value >> 8) & 0xFF);
|
||||
dst[2] = static_cast<uint8_t>((value >> 16) & 0xFF);
|
||||
dst[3] = static_cast<uint8_t>((value >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
static uint16_t readU16(const uint8_t *src) {
|
||||
return static_cast<uint16_t>(src[0]) |
|
||||
(static_cast<uint16_t>(src[1]) << 8);
|
||||
}
|
||||
|
||||
static uint32_t readU32(const uint8_t *src) {
|
||||
return static_cast<uint32_t>(src[0]) |
|
||||
(static_cast<uint32_t>(src[1]) << 8) |
|
||||
(static_cast<uint32_t>(src[2]) << 16) |
|
||||
(static_cast<uint32_t>(src[3]) << 24);
|
||||
}
|
||||
|
||||
int availableStorageSize() {
|
||||
int n = STORAGE_SIZE;
|
||||
if (EEPROM.length() > 0 && EEPROM.length() < n) n = EEPROM.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
bool save() {
|
||||
const int storageSize = availableStorageSize();
|
||||
if (storageSize < 16) return false;
|
||||
|
||||
uint8_t buffer[STORAGE_SIZE] = {};
|
||||
int pos = 0;
|
||||
writeU32(buffer + pos, MAGIC);
|
||||
pos += 4;
|
||||
buffer[pos++] = VERSION;
|
||||
buffer[pos++] = 0;
|
||||
int lengthPos = pos;
|
||||
pos += 2;
|
||||
|
||||
for (int i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (!entries[i].used) continue;
|
||||
if (!entries[i].hasFloat && !entries[i].hasString) continue;
|
||||
|
||||
const uint8_t keyLen = static_cast<uint8_t>(strnlen(entries[i].key, MAX_KEY_LEN));
|
||||
if (keyLen == 0) continue;
|
||||
|
||||
if (entries[i].hasFloat) {
|
||||
const int recordSize = 3 + keyLen + 4;
|
||||
if (pos + recordSize > storageSize) return false;
|
||||
|
||||
buffer[pos++] = TYPE_FLOAT;
|
||||
buffer[pos++] = keyLen;
|
||||
buffer[pos++] = 4;
|
||||
memcpy(buffer + pos, entries[i].key, keyLen);
|
||||
pos += keyLen;
|
||||
float value = entries[i].floatValue;
|
||||
memcpy(buffer + pos, &value, sizeof(value));
|
||||
pos += sizeof(value);
|
||||
} else if (entries[i].hasString) {
|
||||
const uint8_t valueLen = static_cast<uint8_t>(entries[i].stringValue.length());
|
||||
const int recordSize = 3 + keyLen + valueLen;
|
||||
if (pos + recordSize > storageSize) return false;
|
||||
|
||||
buffer[pos++] = TYPE_STRING;
|
||||
buffer[pos++] = keyLen;
|
||||
buffer[pos++] = valueLen;
|
||||
memcpy(buffer + pos, entries[i].key, keyLen);
|
||||
pos += keyLen;
|
||||
if (valueLen > 0) {
|
||||
memcpy(buffer + pos, entries[i].stringValue.c_str(), valueLen);
|
||||
pos += valueLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeU16(buffer + lengthPos, static_cast<uint16_t>(pos));
|
||||
|
||||
for (int i = 0; i < storageSize; i++) {
|
||||
EEPROM.write(i, buffer[i]);
|
||||
}
|
||||
EEPROM.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
void load() {
|
||||
const int storageSize = availableStorageSize();
|
||||
if (storageSize < 16) return;
|
||||
|
||||
for (auto &entry : entries) entry = Entry();
|
||||
|
||||
uint8_t buffer[STORAGE_SIZE] = {};
|
||||
for (int i = 0; i < storageSize; i++) {
|
||||
buffer[i] = EEPROM.read(i);
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
if (readU32(buffer + pos) != MAGIC) return;
|
||||
pos += 4;
|
||||
if (buffer[pos++] != VERSION) return;
|
||||
pos++; // flags
|
||||
|
||||
const uint16_t totalLen = readU16(buffer + pos);
|
||||
pos += 2;
|
||||
if (totalLen < pos || totalLen > storageSize) return;
|
||||
|
||||
while (pos + 3 <= totalLen) {
|
||||
const uint8_t type = buffer[pos++];
|
||||
const uint8_t keyLen = buffer[pos++];
|
||||
const uint8_t valueLen = buffer[pos++];
|
||||
if (keyLen == 0 || keyLen > MAX_KEY_LEN) return;
|
||||
if (pos + keyLen + valueLen > totalLen) return;
|
||||
|
||||
char key[MAX_KEY_LEN + 1] = {};
|
||||
memcpy(key, buffer + pos, keyLen);
|
||||
key[keyLen] = '\0';
|
||||
pos += keyLen;
|
||||
|
||||
int index = ensureKey(key);
|
||||
if (index < 0) return;
|
||||
|
||||
if (type == TYPE_FLOAT && valueLen == 4) {
|
||||
float value = NAN;
|
||||
memcpy(&value, buffer + pos, sizeof(value));
|
||||
entries[index].hasFloat = true;
|
||||
entries[index].hasString = false;
|
||||
entries[index].stringValue = "";
|
||||
entries[index].floatValue = value;
|
||||
} else if (type == TYPE_STRING && valueLen <= MAX_STRING_LEN) {
|
||||
char value[MAX_STRING_LEN + 1] = {};
|
||||
if (valueLen > 0) memcpy(value, buffer + pos, valueLen);
|
||||
value[valueLen] = '\0';
|
||||
entries[index].hasString = true;
|
||||
entries[index].hasFloat = false;
|
||||
entries[index].stringValue = value;
|
||||
}
|
||||
|
||||
pos += valueLen;
|
||||
}
|
||||
}
|
||||
|
||||
int findKey(const char *key) {
|
||||
if (!key) return -1;
|
||||
for (int i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (!entries[i].used) continue;
|
||||
if (strncmp(entries[i].key, key, MAX_KEY_LEN + 1) == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ensureKey(const char *key) {
|
||||
if (!key) return -1;
|
||||
if (strlen(key) > MAX_KEY_LEN) return -1;
|
||||
|
||||
int index = findKey(key);
|
||||
if (index >= 0) return index;
|
||||
|
||||
for (int i = 0; i < MAX_ENTRIES; i++) {
|
||||
if (entries[i].used) continue;
|
||||
entries[i].used = true;
|
||||
entries[i].hasFloat = false;
|
||||
entries[i].hasString = false;
|
||||
entries[i].floatValue = NAN;
|
||||
entries[i].stringValue = "";
|
||||
strncpy(entries[i].key, key, MAX_KEY_LEN);
|
||||
entries[i].key[MAX_KEY_LEN] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -6,11 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
#ifdef ESP32
|
||||
#include <soc/soc.h>
|
||||
#include <soc/rtc_cntl_reg.h>
|
||||
#include <ESP32_NOW_Serial.h>
|
||||
#endif
|
||||
|
||||
const float ONE_G = 9.80665;
|
||||
extern float t;
|
||||
@@ -57,7 +53,6 @@ void splitString(String& str, String& token0, String& token1, String& token2) {
|
||||
if (token2.c_str() == NULL) token2 = "";
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
// Simplified ESP-NOW Serial without resends
|
||||
class ESPNOWSerial : public ESP_NOW_Serial_Class {
|
||||
public:
|
||||
@@ -68,7 +63,6 @@ public:
|
||||
ESP_NOW_Serial_Class::onSent(true); // always report success to avoid resends
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Rate limiter
|
||||
class Rate {
|
||||
|
||||
+96
-97
@@ -3,13 +3,13 @@
|
||||
|
||||
// Wi-Fi and ESP-NOW communication
|
||||
|
||||
// #include <WiFi.h>
|
||||
// #include <WiFiAP.h>
|
||||
// #include <WiFiUdp.h>
|
||||
// #include <MacAddress.h>
|
||||
// #include <ESP32_NOW_Serial.h>
|
||||
// #include "prefs.h"
|
||||
// #include "util.h"
|
||||
#include <WiFi.h>
|
||||
#include <WiFiAP.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <MacAddress.h>
|
||||
#include <ESP32_NOW_Serial.h>
|
||||
#include <Preferences.h>
|
||||
#include "util.h"
|
||||
|
||||
extern Preferences storage; // use the main preferences storage
|
||||
|
||||
@@ -20,121 +20,120 @@ int wifiLongRange = 0;
|
||||
int wifiBroadcast = 0; // 0 - broadcast until connected, 1 - always broadcast
|
||||
int udpLocalPort = 14550;
|
||||
int udpRemotePort = 14550;
|
||||
// IPAddress udpRemoteIP = "255.255.255.255";
|
||||
// WiFiUDP udp;
|
||||
IPAddress udpRemoteIP = "255.255.255.255";
|
||||
WiFiUDP udp;
|
||||
|
||||
// ESPNOWSerial espnow(NULL, 0, WIFI_IF_AP);
|
||||
// ESPNOWSerial espnowBroadcast(ESP_NOW.BROADCAST_ADDR, 0, WIFI_IF_AP);
|
||||
ESPNOWSerial espnow(NULL, 0, WIFI_IF_AP);
|
||||
ESPNOWSerial espnowBroadcast(ESP_NOW.BROADCAST_ADDR, 0, WIFI_IF_AP);
|
||||
int espnowChannel = 6;
|
||||
|
||||
void setupWiFi() {
|
||||
// print("Setup Wi-Fi\n");
|
||||
// WiFi.enableLongRange(wifiLongRange);
|
||||
print("Setup Wi-Fi\n");
|
||||
WiFi.enableLongRange(wifiLongRange);
|
||||
|
||||
// if (wifiMode == W_AP) {
|
||||
// WiFi.softAP(storage.getString("WIFI_AP_SSID", "flix").c_str(), storage.getString("WIFI_AP_PASS", "flixwifi").c_str());
|
||||
// udp.begin(udpLocalPort);
|
||||
// }
|
||||
if (wifiMode == W_AP) {
|
||||
WiFi.softAP(storage.getString("WIFI_AP_SSID", "flix").c_str(), storage.getString("WIFI_AP_PASS", "flixwifi").c_str());
|
||||
udp.begin(udpLocalPort);
|
||||
}
|
||||
|
||||
// if (wifiMode == W_STA) {
|
||||
// WiFi.begin(storage.getString("WIFI_STA_SSID", "").c_str(), storage.getString("WIFI_STA_PASS", "").c_str());
|
||||
// udp.begin(udpLocalPort);
|
||||
// }
|
||||
if (wifiMode == W_STA) {
|
||||
WiFi.begin(storage.getString("WIFI_STA_SSID", "").c_str(), storage.getString("WIFI_STA_PASS", "").c_str());
|
||||
udp.begin(udpLocalPort);
|
||||
}
|
||||
|
||||
// if (wifiMode == W_ESPNOW) {
|
||||
// WiFi.mode(WIFI_AP);
|
||||
// WiFi.setChannel(espnowChannel);
|
||||
// espnow.addr(MacAddress(storage.getString("ESPNOW_PEER_MAC", "FF:FF:FF:FF:FF:FF").c_str()));
|
||||
// String key = storage.getString("ESPNOW_PEER_KEY", "");
|
||||
// espnow.setKey(key.isEmpty() ? nullptr : (const uint8_t *)key.c_str());
|
||||
// espnow.begin();
|
||||
// espnowBroadcast.begin();
|
||||
// }
|
||||
if (wifiMode == W_ESPNOW) {
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.setChannel(espnowChannel);
|
||||
espnow.addr(MacAddress(storage.getString("ESPNOW_PEER_MAC", "FF:FF:FF:FF:FF:FF").c_str()));
|
||||
String key = storage.getString("ESPNOW_PEER_KEY", "");
|
||||
espnow.setKey(key.isEmpty() ? nullptr : (const uint8_t *)key.c_str());
|
||||
espnow.begin();
|
||||
espnowBroadcast.begin();
|
||||
}
|
||||
|
||||
// WiFi.setSleep(false); // disable power save
|
||||
WiFi.setSleep(false); // disable power save
|
||||
}
|
||||
|
||||
void sendWiFi(const uint8_t *buf, int len) {
|
||||
// if (espnow) {
|
||||
// espnow.write(buf, len);
|
||||
if (espnow) {
|
||||
espnow.write(buf, len);
|
||||
|
||||
// static Rate discovery(2);
|
||||
// if (espnow.isEncrypted() && discovery) espnowBroadcast.write((const uint8_t *)"flix", 4); // broadcast message to help finding this device
|
||||
// return;
|
||||
// }
|
||||
static Rate discovery(2);
|
||||
if (espnow.isEncrypted() && discovery) espnowBroadcast.write((const uint8_t *)"flix", 4); // broadcast message to help finding this device
|
||||
return;
|
||||
}
|
||||
|
||||
// if (WiFi.softAPgetStationNum() == 0 && !WiFi.isConnected()) return;
|
||||
if (WiFi.softAPgetStationNum() == 0 && !WiFi.isConnected()) return;
|
||||
|
||||
// bool broadcast = wifiBroadcast || !(t - mavlinkTime < 5); // broadcast if lost connection
|
||||
// udp.beginPacket(broadcast ? IPAddress(255, 255, 255, 255) : udpRemoteIP, udpRemotePort);
|
||||
// udp.write(buf, len);
|
||||
// udp.endPacket();
|
||||
bool broadcast = wifiBroadcast || !(t - mavlinkTime < 5); // broadcast if lost connection
|
||||
udp.beginPacket(broadcast ? IPAddress(255, 255, 255, 255) : udpRemoteIP, udpRemotePort);
|
||||
udp.write(buf, len);
|
||||
udp.endPacket();
|
||||
}
|
||||
|
||||
int receiveWiFi(uint8_t *buf, int len) {
|
||||
// if (espnow) {
|
||||
// return espnow.read(buf, len);
|
||||
// }
|
||||
if (espnow) {
|
||||
return espnow.read(buf, len);
|
||||
}
|
||||
|
||||
// if (WiFi.softAPgetStationNum() == 0 && !WiFi.isConnected()) return 0;
|
||||
if (WiFi.softAPgetStationNum() == 0 && !WiFi.isConnected()) return 0;
|
||||
|
||||
// udp.parsePacket();
|
||||
// if (udp.remoteIP()) udpRemoteIP = udp.remoteIP();
|
||||
// return udp.read(buf, len);
|
||||
return 0;
|
||||
udp.parsePacket();
|
||||
if (udp.remoteIP()) udpRemoteIP = udp.remoteIP();
|
||||
return udp.read(buf, len);
|
||||
}
|
||||
|
||||
void printWiFiInfo() {
|
||||
// if (espnow) {
|
||||
// print("Mode: ESP-NOW\n");
|
||||
// print("ESP-NOW version: %d\n", ESP_NOW.getVersion());
|
||||
// print("Max packet size: %d\n", ESP_NOW.getMaxDataLen());
|
||||
// print("MAC: %s\n", WiFi.softAPmacAddress().c_str());
|
||||
// print("Peer MAC: %s\n", MacAddress(espnow.addr()).toString().c_str());
|
||||
// print("Encrypted: %d\n", espnow.isEncrypted());
|
||||
// print("Channel: %d\n", espnow.getChannel());
|
||||
// print("Lost packets: %d\n", espnow.lost);
|
||||
// } else if (WiFi.getMode() == WIFI_MODE_AP) {
|
||||
// print("Mode: Access Point (AP)\n");
|
||||
// print("MAC: %s\n", WiFi.softAPmacAddress().c_str());
|
||||
// print("SSID: %s\n", WiFi.softAPSSID().c_str());
|
||||
// print("Password: ***\n");
|
||||
// print("Channel: %d\n", WiFi.channel());
|
||||
// print("Clients: %d\n", WiFi.softAPgetStationNum());
|
||||
// print("IP: %s\n", WiFi.softAPIP().toString().c_str());
|
||||
// print("Remote IP: %s\n", udpRemoteIP.toString().c_str());
|
||||
// } else if (WiFi.getMode() == WIFI_MODE_STA) {
|
||||
// print("Mode: Client (STA)\n");
|
||||
// print("Connected: %d\n", WiFi.isConnected());
|
||||
// print("MAC: %s\n", WiFi.macAddress().c_str());
|
||||
// print("SSID: %s\n", WiFi.SSID().c_str());
|
||||
// print("Password: ***\n");
|
||||
// print("Channel: %d\n", WiFi.channel());
|
||||
// print("RSSI: %d dBm\n", WiFi.RSSI());
|
||||
// print("IP: %s\n", WiFi.localIP().toString().c_str());
|
||||
// print("Remote IP: %s\n", udpRemoteIP.toString().c_str());
|
||||
// } else {
|
||||
// print("Mode: Disabled\n");
|
||||
// }
|
||||
// print("MAVLink connected: %d\n", valid(mavlinkTime));
|
||||
if (espnow) {
|
||||
print("Mode: ESP-NOW\n");
|
||||
print("ESP-NOW version: %d\n", ESP_NOW.getVersion());
|
||||
print("Max packet size: %d\n", ESP_NOW.getMaxDataLen());
|
||||
print("MAC: %s\n", WiFi.softAPmacAddress().c_str());
|
||||
print("Peer MAC: %s\n", MacAddress(espnow.addr()).toString().c_str());
|
||||
print("Encrypted: %d\n", espnow.isEncrypted());
|
||||
print("Channel: %d\n", espnow.getChannel());
|
||||
print("Lost packets: %d\n", espnow.lost);
|
||||
} else if (WiFi.getMode() == WIFI_MODE_AP) {
|
||||
print("Mode: Access Point (AP)\n");
|
||||
print("MAC: %s\n", WiFi.softAPmacAddress().c_str());
|
||||
print("SSID: %s\n", WiFi.softAPSSID().c_str());
|
||||
print("Password: ***\n");
|
||||
print("Channel: %d\n", WiFi.channel());
|
||||
print("Clients: %d\n", WiFi.softAPgetStationNum());
|
||||
print("IP: %s\n", WiFi.softAPIP().toString().c_str());
|
||||
print("Remote IP: %s\n", udpRemoteIP.toString().c_str());
|
||||
} else if (WiFi.getMode() == WIFI_MODE_STA) {
|
||||
print("Mode: Client (STA)\n");
|
||||
print("Connected: %d\n", WiFi.isConnected());
|
||||
print("MAC: %s\n", WiFi.macAddress().c_str());
|
||||
print("SSID: %s\n", WiFi.SSID().c_str());
|
||||
print("Password: ***\n");
|
||||
print("Channel: %d\n", WiFi.channel());
|
||||
print("RSSI: %d dBm\n", WiFi.RSSI());
|
||||
print("IP: %s\n", WiFi.localIP().toString().c_str());
|
||||
print("Remote IP: %s\n", udpRemoteIP.toString().c_str());
|
||||
} else {
|
||||
print("Mode: Disabled\n");
|
||||
}
|
||||
print("MAVLink connected: %d\n", valid(mavlinkTime));
|
||||
}
|
||||
|
||||
void configWiFi(int mode, const char *first, const char *second) {
|
||||
// MacAddress mac;
|
||||
// if (mode == W_AP && strlen(first) > 0 && strlen(second) >= 8) {
|
||||
// storage.putString("WIFI_AP_SSID", first);
|
||||
// storage.putString("WIFI_AP_PASS", second);
|
||||
// } else if (mode == W_STA && strlen(first) > 0 && strlen(second) >= 8) {
|
||||
// storage.putString("WIFI_STA_SSID", first);
|
||||
// storage.putString("WIFI_STA_PASS", second);
|
||||
// } else if (mode == W_ESPNOW && mac.fromString(first)) {
|
||||
// storage.putString("ESPNOW_PEER_MAC", first);
|
||||
// storage.putString("ESPNOW_PEER_KEY", strlen(second) == ESP_NOW_KEY_LEN ? second : "");
|
||||
// } else {
|
||||
// print("Invalid configuration\n");
|
||||
// return;
|
||||
// }
|
||||
// print("✓ Reboot to apply new settings\n");
|
||||
MacAddress mac;
|
||||
if (mode == W_AP && strlen(first) > 0 && strlen(second) >= 8) {
|
||||
storage.putString("WIFI_AP_SSID", first);
|
||||
storage.putString("WIFI_AP_PASS", second);
|
||||
} else if (mode == W_STA && strlen(first) > 0 && strlen(second) >= 8) {
|
||||
storage.putString("WIFI_STA_SSID", first);
|
||||
storage.putString("WIFI_STA_PASS", second);
|
||||
} else if (mode == W_ESPNOW && mac.fromString(first)) {
|
||||
storage.putString("ESPNOW_PEER_MAC", first);
|
||||
storage.putString("ESPNOW_PEER_KEY", strlen(second) == ESP_NOW_KEY_LEN ? second : "");
|
||||
} else {
|
||||
print("Invalid configuration\n");
|
||||
return;
|
||||
}
|
||||
print("✓ Reboot to apply new settings\n");
|
||||
}
|
||||
|
||||
void setWiFiMode(const String& mode) {
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
#include "quaternion.h"
|
||||
#include "Arduino.h"
|
||||
#include "wifi.h"
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
|
||||
extern float t, dt;
|
||||
extern float controlRoll, controlPitch, controlYaw, controlThrottle, controlMode;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "estimate.ino"
|
||||
#include "safety.ino"
|
||||
#include "log.ino"
|
||||
#include "lpf.h"
|
||||
#include "filter.h"
|
||||
#include "mavlink.ino"
|
||||
#include "motors.ino"
|
||||
#include "parameters.ino"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// Mocks
|
||||
int wifiMode = 1;
|
||||
int wifiLongRange = 0;
|
||||
int wifiBroadcast = 0;
|
||||
int espnowChannel = 6;
|
||||
const int W_DISABLED = 0, W_AP = 1, W_STA = 2, W_ESPNOW = 3;
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ class Flix:
|
||||
time.sleep(1)
|
||||
|
||||
@staticmethod
|
||||
def _mavlink_to_flu(v: List[float]) -> List[float]:
|
||||
def _mavlink_to_flu(v: Sequence[float]) -> List[float]:
|
||||
if len(v) == 3: # vector
|
||||
return [v[0], -v[1], -v[2]]
|
||||
elif len(v) == 4: # quaternion
|
||||
@@ -252,8 +252,8 @@ class Flix:
|
||||
raise ValueError(f'List must have 3 (vector) or 4 (quaternion) elements')
|
||||
|
||||
@staticmethod
|
||||
def _flu_to_mavlink(v: List[float]) -> List[float]:
|
||||
return Flix._mavlink_to_flu(v)
|
||||
def _flu_to_mavlink(v: Sequence[float]) -> List[float]:
|
||||
return Flix._mavlink_to_flu(v) # flu to mavlink is the same as mavlink to flu
|
||||
|
||||
def _command_send(self, command: int, params: Sequence[float]):
|
||||
if len(params) != 7:
|
||||
@@ -320,13 +320,13 @@ class Flix:
|
||||
def set_armed(self, armed: bool):
|
||||
self._command_send(mavlink.MAV_CMD_COMPONENT_ARM_DISARM, (1 if armed else 0, 0, 0, 0, 0, 0, 0))
|
||||
|
||||
def set_position(self, position: List[float], yaw: Optional[float] = None, wait: bool = False, tolerance: float = 0.1):
|
||||
def set_position(self, position: Sequence[float], yaw: Optional[float] = None, wait: bool = False, tolerance: float = 0.1):
|
||||
raise NotImplementedError('Position control is not implemented yet')
|
||||
|
||||
def set_velocity(self, velocity: List[float], yaw: Optional[float] = None):
|
||||
def set_velocity(self, velocity: Sequence[float], yaw: Optional[float] = None):
|
||||
raise NotImplementedError('Velocity control is not implemented yet')
|
||||
|
||||
def set_attitude(self, attitude: List[float], thrust: float):
|
||||
def set_attitude(self, attitude: Sequence[float], thrust: float):
|
||||
if len(attitude) == 3:
|
||||
attitude = Quaternion([attitude[0], attitude[1], attitude[2]]).q # type: ignore
|
||||
elif len(attitude) != 4:
|
||||
@@ -339,7 +339,7 @@ class Flix:
|
||||
[attitude[0], attitude[1], attitude[2], attitude[3]],
|
||||
0, 0, 0, thrust)
|
||||
|
||||
def set_rates(self, rates: List[float], thrust: float):
|
||||
def set_rates(self, rates: Sequence[float], thrust: float):
|
||||
if len(rates) != 3:
|
||||
raise ValueError('Rates must be [roll_rate, pitch_rate, yaw_rate]')
|
||||
if not (0 <= thrust <= 1):
|
||||
@@ -351,7 +351,7 @@ class Flix:
|
||||
[1, 0, 0, 0],
|
||||
rates[0], rates[1], rates[2], thrust)
|
||||
|
||||
def set_motors(self, motors: List[float]):
|
||||
def set_motors(self, motors: Sequence[float]):
|
||||
if len(motors) != 4:
|
||||
raise ValueError('motors must have 4 values')
|
||||
if not all(0 <= m <= 1 for m in motors):
|
||||
|
||||
Reference in New Issue
Block a user