From fd249fcaa68e6268da6388a464103bc06680a0ec Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Sat, 1 Aug 2026 22:33:26 +0300 Subject: [PATCH 1/6] Add position control demo video to the readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 8d277c7..f1bc75e 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,12 @@ Outdoor flights demo video of the current prototype: +### Position control + +The position control feature is in development. RoboCamp 2026 demo (using an overhead camera, [sources](https://github.com/xTimop/flix-poscontrol/compare/robolager2026...xTimop:flix-poscontrol:poscontrol)): + + + ## Simulation The simulator is implemented using Gazebo and runs the original Arduino code: From 5c811812212b168345ba47fee356761848e1d6f2 Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Sun, 2 Aug 2026 01:58:16 +0300 Subject: [PATCH 2/6] Add threshold for rc sticks move for quitting auto mode --- flix/safety.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flix/safety.ino b/flix/safety.ino index 05fd758..7cbd986 100644 --- a/flix/safety.ino +++ b/flix/safety.ino @@ -36,7 +36,7 @@ void descend() { // Allow pilot to interrupt automatic flight void autoFailsafe() { static float roll, pitch, yaw, throttle; - if (roll != controlRoll || pitch != controlPitch || yaw != controlYaw || abs(throttle - controlThrottle) > 0.05) { + if (abs(roll - controlRoll) > 0.05 || abs(pitch - controlPitch) > 0.05 || abs(yaw - controlYaw) > 0.05 || abs(throttle - controlThrottle) > 0.05) { // controls changed and mode switch is not configured if (mode == AUTO && invalid(controlMode)) mode = STAB; // regain control by the pilot } From 38925d788553c41da454736f47b1606a419bd109 Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Sun, 2 Aug 2026 02:02:28 +0300 Subject: [PATCH 3/6] Updates and fixes in usage article --- docs/usage.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 35f4a67..0f26f1e 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -25,7 +25,7 @@ You can build and upload the firmware using either **Arduino IDE** (easier for b * `FlixPeriph`, the latest version. * `MAVLink`, version 2.0.25. 5. Open the `flix/flix.ino` sketch from downloaded firmware sources in Arduino IDE. -6. Connect your ESP32 board to the computer and choose correct board type in Arduino IDE (*WEMOS D1 MINI ESP32* for ESP32 Mini) and the port. +6. Connect your ESP32 board to the computer and choose correct board type in Arduino IDE (*WEMOS D1 MINI ESP32* for ESP32 Mini, *ESP32S3 Dev Module* for ESP32-S3 Super Mini) and the port. 7. Set *Tools* ⇒ *Core Debug Level* to *Error* to see the errors in the serial console. Set *Tools* ⇒ *USB CDC on Boot* to *Enabled* for ESP32-S3/ESP32-C3 boards. 8. [Build and upload](https://docs.arduino.cc/software/ide-v2/tutorials/getting-started/ide-v2-uploading-a-sketch) the firmware using Arduino IDE. @@ -105,7 +105,7 @@ To access the console using serial port: To access the console using QGroundControl: 1. Connect to the drone using QGroundControl app. -2. Go to the QGroundControl menu ⇒ *Vehicle Setup* ⇒ *Analyze Tools* ⇒ *MAVLink Console*. +2. Go to the QGroundControl menu ⇒ *Analyze Tools* ⇒ *MAVLink Console*. @@ -333,7 +333,7 @@ To setup ESP-NOW communication: 1. Flash the second ESP32 board with ESP-NOW proxy sketch: [`tools/espnow-proxy/espnow-proxy.ino`](../tools/espnow-proxy/espnow-proxy.ino). Use Arduino IDE or command line: `make upload_proxy`. -2. Open Serial Monitor or use `make monitor` command. The ESP32 will print its MAC address and generated encryption key, for example: +2. Open Serial Monitor in Arduino IDE or use `make monitor` command. The ESP32 will print its MAC address and generated encryption key, for example: ``` espnow 7a:c8:e3:eb:bf:e9 &PiuSysxP9+$L&5E @@ -352,7 +352,10 @@ To setup ESP-NOW communication: * Type: Serial. * Serial Port: choose the port of the proxy ESP32 board, e. g. `/dev/cu.usbserial-0001`. * Baud Rate: 115200. -5. Click *Save*. QGroundControl should connect to the drone using ESP-NOW and begin showing the telemetry. +5. Click *Save*, click *Connect*. QGroundControl should connect to the drone using ESP-NOW and begin showing the telemetry. + +> [!TIP] +> Make sure Arduino IDE is not running when using ESP-NOW proxy board, as it may block the serial port. ## Flight log From 5ee6d9144041d1ce33e4e3fde51264cfc4f675f1 Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Sun, 2 Aug 2026 02:07:17 +0300 Subject: [PATCH 4/6] Don't send discovery message if encrypting is disabled in espnow --- flix/wifi.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flix/wifi.ino b/flix/wifi.ino index eea9d8a..f316f83 100644 --- a/flix/wifi.ino +++ b/flix/wifi.ino @@ -58,7 +58,7 @@ void sendWiFi(const uint8_t *buf, int len) { espnow.write(buf, len); static Rate discovery(2); - if (discovery) espnowBroadcast.write((const uint8_t *)"flix", 4); // broadcast message to help finding this device + if (espnow.isEncrypted() && discovery) espnowBroadcast.write((const uint8_t *)"flix", 4); // broadcast message to help finding this device return; } From 406f7a4af5471ff9f3117b566529c32e261f63d7 Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Sun, 2 Aug 2026 02:13:50 +0300 Subject: [PATCH 5/6] Add tilt disarm failsafe --- flix/parameters.ino | 3 ++- flix/safety.ino | 14 ++++++++++++++ gazebo/flix.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/flix/parameters.ino b/flix/parameters.ino index 0d3e19a..ebabaaf 100644 --- a/flix/parameters.ino +++ b/flix/parameters.ino @@ -10,7 +10,7 @@ extern int channelZero[16], channelMax[16]; extern int rollChannel, pitchChannel, throttleChannel, yawChannel, armedChannel, modeChannel; extern int rcRxPin, voltagePin; extern int wifiMode, wifiLongRange, udpLocalPort, udpRemotePort, espnowChannel; -extern float rcLossTimeout, descendTime; +extern float rcLossTimeout, descendTime, disarmTilt; extern float voltageScale; extern LowPassFilter voltageFilter; @@ -128,6 +128,7 @@ Parameter parameters[] = { // safety {"SF_RC_LOSS_TIME", &rcLossTimeout}, {"SF_DESCEND_TIME", &descendTime}, + {"SF_DISARM_TILT", &disarmTilt}, }; void setupParameters() { diff --git a/flix/safety.ino b/flix/safety.ino index 7cbd986..4e7e9dc 100644 --- a/flix/safety.ino +++ b/flix/safety.ino @@ -8,10 +8,12 @@ extern float controlRoll, controlPitch, controlThrottle, controlYaw; float rcLossTimeout = 1; float descendTime = 10; +float disarmTilt = radians(120); void failsafe() { rcLossFailsafe(); autoFailsafe(); + tiltFailsafe(); } // RC loss failsafe @@ -45,3 +47,15 @@ void autoFailsafe() { yaw = controlYaw; throttle = controlThrottle; } + +// Disarm if tilted too much +void tiltFailsafe() { + if (!armed) return; + if (mode != STAB) return; + + Vector up = Quaternion::rotateVector(Vector(0, 0, 1), attitude); + float tilt = acos(up.z); + if (disarmTilt && tilt > disarmTilt) { + armed = false; + } +} diff --git a/gazebo/flix.h b/gazebo/flix.h index 0cc02c2..1d88343 100644 --- a/gazebo/flix.h +++ b/gazebo/flix.h @@ -63,6 +63,7 @@ void failsafe(); void rcLossFailsafe(); void descend(); void autoFailsafe(); +void tiltFailsafe(); int parametersCount(); const char *getParameterName(int index); float getParameter(int index); From a5991930d1899ab4e03202668f5e9a6f12abedcb Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Mon, 3 Aug 2026 15:57:29 +0300 Subject: [PATCH 6/6] Disable voltage lpf by default Filtering does more harm than good in voltage monitoring. (alpha = 1 efficiently disables the filter.) --- flix/power.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flix/power.ino b/flix/power.ino index b79a898..93e3038 100644 --- a/flix/power.ino +++ b/flix/power.ino @@ -9,7 +9,7 @@ #include "util.h" float voltage = NAN; -LowPassFilter voltageFilter(0.2); +LowPassFilter voltageFilter(1); int voltagePin = -1; float voltageScale = 2;