5 Commits

Author SHA1 Message Date
Oleg Kalachev
8a12d1fa70 Add parameters for mavlink subsystem
System ID, fast telemetry rate, slow telemetry rate.
2026-01-19 01:28:43 +03:00
Oleg Kalachev
a7cd6473fd Remove WIFI_ENABLED ci build 2026-01-19 01:09:40 +03:00
Oleg Kalachev
5960e85a74 Don't send param_ack if parameter is not set 2026-01-19 01:08:29 +03:00
Oleg Kalachev
cef1834ea3 Implement wi-fi configuration
Add console commands to setup wi-fi
Add parameter for choosing between STA and AP mode.
Add parameter for udp ports.
Remove WIFI_ENABLED macro.
2026-01-19 00:53:36 +03:00
Oleg Kalachev
6548ae5708 Add possibility to use int variables as parameters
In addition to floats.
2026-01-18 21:24:44 +03:00
9 changed files with 44 additions and 60 deletions

View File

@@ -25,8 +25,6 @@ jobs:
path: flix/build path: flix/build
- name: Build firmware for ESP32-S3 - name: Build firmware for ESP32-S3
run: make BOARD=esp32:esp32:esp32s3 run: make BOARD=esp32:esp32:esp32s3
- name: Build firmware for ESP32-C3
run: make BOARD=esp32:esp32:esp32c3
- name: Check c_cpp_properties.json - name: Check c_cpp_properties.json
run: tools/check_c_cpp_properties.py run: tools/check_c_cpp_properties.py

View File

@@ -6,18 +6,19 @@
"${workspaceFolder}/flix", "${workspaceFolder}/flix",
"${workspaceFolder}/gazebo", "${workspaceFolder}/gazebo",
"${workspaceFolder}/tools/**", "${workspaceFolder}/tools/**",
"~/.arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32", "~/.arduino15/packages/esp32/hardware/esp32/3.2.0/cores/esp32",
"~/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/**", "~/.arduino15/packages/esp32/hardware/esp32/3.2.0/libraries/**",
"~/.arduino15/packages/esp32/hardware/esp32/3.3.6/variants/d1_mini32", "~/.arduino15/packages/esp32/hardware/esp32/3.2.0/variants/d1_mini32",
"~/.arduino15/packages/esp32/tools/esp32-libs/3.3.6/include/**", "~/.arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.4-2f7dcd86-v1/esp32/**",
"~/.arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.4-2f7dcd86-v1/esp32/dio_qspi/include",
"~/Arduino/libraries/**", "~/Arduino/libraries/**",
"/usr/include/gazebo-11/", "/usr/include/gazebo-11/",
"/usr/include/ignition/math6/" "/usr/include/ignition/math6/"
], ],
"forcedInclude": [ "forcedInclude": [
"${workspaceFolder}/.vscode/intellisense.h", "${workspaceFolder}/.vscode/intellisense.h",
"~/.arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32/Arduino.h", "~/.arduino15/packages/esp32/hardware/esp32/3.2.0/cores/esp32/Arduino.h",
"~/.arduino15/packages/esp32/hardware/esp32/3.3.6/variants/d1_mini32/pins_arduino.h", "~/.arduino15/packages/esp32/hardware/esp32/3.2.0/variants/d1_mini32/pins_arduino.h",
"${workspaceFolder}/flix/cli.ino", "${workspaceFolder}/flix/cli.ino",
"${workspaceFolder}/flix/control.ino", "${workspaceFolder}/flix/control.ino",
"${workspaceFolder}/flix/estimate.ino", "${workspaceFolder}/flix/estimate.ino",
@@ -30,10 +31,9 @@
"${workspaceFolder}/flix/rc.ino", "${workspaceFolder}/flix/rc.ino",
"${workspaceFolder}/flix/time.ino", "${workspaceFolder}/flix/time.ino",
"${workspaceFolder}/flix/wifi.ino", "${workspaceFolder}/flix/wifi.ino",
"${workspaceFolder}/flix/parameters.ino", "${workspaceFolder}/flix/parameters.ino"
"${workspaceFolder}/flix/safety.ino"
], ],
"compilerPath": "~/.arduino15/packages/esp32/tools/esp-x32/2511/bin/xtensa-esp32-elf-g++", "compilerPath": "~/.arduino15/packages/esp32/tools/esp-x32/2411/bin/xtensa-esp32-elf-g++",
"cStandard": "c11", "cStandard": "c11",
"cppStandard": "c++17", "cppStandard": "c++17",
"defines": [ "defines": [
@@ -53,18 +53,19 @@
"name": "Mac", "name": "Mac",
"includePath": [ "includePath": [
"${workspaceFolder}/flix", "${workspaceFolder}/flix",
"~/Library/Arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32", "~/Library/Arduino15/packages/esp32/hardware/esp32/3.2.0/cores/esp32",
"~/Library/Arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/**", "~/Library/Arduino15/packages/esp32/hardware/esp32/3.2.0/libraries/**",
"~/Library/Arduino15/packages/esp32/hardware/esp32/3.3.6/variants/d1_mini32", "~/Library/Arduino15/packages/esp32/hardware/esp32/3.2.0/variants/d1_mini32",
"~/Library/Arduino15/packages/esp32/tools/esp32-libs/3.3.6/include/**", "~/Library/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.4-2f7dcd86-v1/esp32/include/**",
"~/Library/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.4-2f7dcd86-v1/esp32/dio_qspi/include",
"~/Documents/Arduino/libraries/**", "~/Documents/Arduino/libraries/**",
"/opt/homebrew/include/gazebo-11/", "/opt/homebrew/include/gazebo-11/",
"/opt/homebrew/include/ignition/math6/" "/opt/homebrew/include/ignition/math6/"
], ],
"forcedInclude": [ "forcedInclude": [
"${workspaceFolder}/.vscode/intellisense.h", "${workspaceFolder}/.vscode/intellisense.h",
"~/Library/Arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32/Arduino.h", "~/Library/Arduino15/packages/esp32/hardware/esp32/3.2.0/cores/esp32/Arduino.h",
"~/Library/Arduino15/packages/esp32/hardware/esp32/3.3.6/variants/d1_mini32/pins_arduino.h", "~/Library/Arduino15/packages/esp32/hardware/esp32/3.2.0/variants/d1_mini32/pins_arduino.h",
"${workspaceFolder}/flix/flix.ino", "${workspaceFolder}/flix/flix.ino",
"${workspaceFolder}/flix/cli.ino", "${workspaceFolder}/flix/cli.ino",
"${workspaceFolder}/flix/control.ino", "${workspaceFolder}/flix/control.ino",
@@ -77,10 +78,9 @@
"${workspaceFolder}/flix/rc.ino", "${workspaceFolder}/flix/rc.ino",
"${workspaceFolder}/flix/time.ino", "${workspaceFolder}/flix/time.ino",
"${workspaceFolder}/flix/wifi.ino", "${workspaceFolder}/flix/wifi.ino",
"${workspaceFolder}/flix/parameters.ino", "${workspaceFolder}/flix/parameters.ino"
"${workspaceFolder}/flix/safety.ino"
], ],
"compilerPath": "~/Library/Arduino15/packages/esp32/tools/esp-x32/2511/bin/xtensa-esp32-elf-g++", "compilerPath": "~/Library/Arduino15/packages/esp32/tools/esp-x32/2411/bin/xtensa-esp32-elf-g++",
"cStandard": "c11", "cStandard": "c11",
"cppStandard": "c++17", "cppStandard": "c++17",
"defines": [ "defines": [
@@ -103,16 +103,17 @@
"${workspaceFolder}/flix", "${workspaceFolder}/flix",
"${workspaceFolder}/gazebo", "${workspaceFolder}/gazebo",
"${workspaceFolder}/tools/**", "${workspaceFolder}/tools/**",
"~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32", "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.2.0/cores/esp32",
"~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.6/libraries/**", "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.2.0/libraries/**",
"~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.6/variants/d1_mini32", "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.2.0/variants/d1_mini32",
"~/AppData/Local/Arduino15/packages/esp32/tools/esp32-libs/3.3.6/include/**", "~/AppData/Local/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.4-2f7dcd86-v1/esp32/**",
"~/AppData/Local/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.4-2f7dcd86-v1/esp32/dio_qspi/include",
"~/Documents/Arduino/libraries/**" "~/Documents/Arduino/libraries/**"
], ],
"forcedInclude": [ "forcedInclude": [
"${workspaceFolder}/.vscode/intellisense.h", "${workspaceFolder}/.vscode/intellisense.h",
"~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32/Arduino.h", "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.2.0/cores/esp32/Arduino.h",
"~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.3.6/variants/d1_mini32/pins_arduino.h", "~/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.2.0/variants/d1_mini32/pins_arduino.h",
"${workspaceFolder}/flix/cli.ino", "${workspaceFolder}/flix/cli.ino",
"${workspaceFolder}/flix/control.ino", "${workspaceFolder}/flix/control.ino",
"${workspaceFolder}/flix/estimate.ino", "${workspaceFolder}/flix/estimate.ino",
@@ -125,10 +126,9 @@
"${workspaceFolder}/flix/rc.ino", "${workspaceFolder}/flix/rc.ino",
"${workspaceFolder}/flix/time.ino", "${workspaceFolder}/flix/time.ino",
"${workspaceFolder}/flix/wifi.ino", "${workspaceFolder}/flix/wifi.ino",
"${workspaceFolder}/flix/parameters.ino", "${workspaceFolder}/flix/parameters.ino"
"${workspaceFolder}/flix/safety.ino"
], ],
"compilerPath": "~/AppData/Local/Arduino15/packages/esp32/tools/esp-x32/2511/bin/xtensa-esp32-elf-g++.exe", "compilerPath": "~/AppData/Local/Arduino15/packages/esp32/tools/esp-x32/2411/bin/xtensa-esp32-elf-g++.exe",
"cStandard": "c11", "cStandard": "c11",
"cppStandard": "c++17", "cppStandard": "c++17",
"defines": [ "defines": [

View File

@@ -13,10 +13,10 @@ monitor:
dependencies .dependencies: dependencies .dependencies:
arduino-cli core update-index --config-file arduino-cli.yaml arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install esp32:esp32@3.3.6 --config-file arduino-cli.yaml arduino-cli core install esp32:esp32@3.2.0 --config-file arduino-cli.yaml
arduino-cli lib update-index arduino-cli lib update-index
arduino-cli lib install "FlixPeriph" arduino-cli lib install "FlixPeriph"
arduino-cli lib install "MAVLink"@2.0.25 arduino-cli lib install "MAVLink"@2.0.16
touch .dependencies touch .dependencies
gazebo/build cmake: gazebo/CMakeLists.txt gazebo/build cmake: gazebo/CMakeLists.txt

View File

@@ -20,10 +20,10 @@ You can build and upload the firmware using either **Arduino IDE** (easier for b
1. Install [Arduino IDE](https://www.arduino.cc/en/software) (version 2 is recommended). 1. Install [Arduino IDE](https://www.arduino.cc/en/software) (version 2 is recommended).
2. *Windows users might need to install [USB to UART bridge driver from Silicon Labs](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers).* 2. *Windows users might need to install [USB to UART bridge driver from Silicon Labs](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers).*
3. Install ESP32 core, version 3.3.6. See the [official Espressif's instructions](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html#installing-using-arduino-ide) on installing ESP32 Core in Arduino IDE. 3. Install ESP32 core, version 3.2.0. See the [official Espressif's instructions](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html#installing-using-arduino-ide) on installing ESP32 Core in Arduino IDE.
4. Install the following libraries using [Library Manager](https://docs.arduino.cc/software/ide-v2/tutorials/ide-v2-installing-a-library): 4. Install the following libraries using [Library Manager](https://docs.arduino.cc/software/ide-v2/tutorials/ide-v2-installing-a-library):
* `FlixPeriph`, the latest version. * `FlixPeriph`, the latest version.
* `MAVLink`, version 2.0.25. * `MAVLink`, version 2.0.16.
5. Open the `flix/flix.ino` sketch from downloaded firmware sources in Arduino IDE. 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) and the port.
7. [Build and upload](https://docs.arduino.cc/software/ide-v2/tutorials/getting-started/ide-v2-uploading-a-sketch) the firmware using Arduino IDE. 7. [Build and upload](https://docs.arduino.cc/software/ide-v2/tutorials/getting-started/ide-v2-uploading-a-sketch) the firmware using Arduino IDE.
@@ -108,7 +108,7 @@ The drone is configured using parameters. To access and modify them, go to the Q
<img src="img/parameters.png" width="400"> <img src="img/parameters.png" width="400">
You can also work with parameters using `p` command in the console. Parameter names are case-insensitive. You can also work with parameters using `p` command in the console.
### Define IMU orientation ### Define IMU orientation
@@ -271,12 +271,6 @@ ap my-flix-ssid mypassword123
p WIFI_MODE 1 p WIFI_MODE 1
``` ```
Disabling Wi-Fi:
```
p WIFI_MODE 0
```
## Flight log ## Flight log
After the flight, you can download the flight log for analysis wirelessly. Use the following command on your computer for that: After the flight, you can download the flight log for analysis wirelessly. Use the following command on your computer for that:

View File

@@ -10,7 +10,6 @@ extern float channelZero[16];
extern float channelMax[16]; extern float channelMax[16];
extern float rollChannel, pitchChannel, throttleChannel, yawChannel, armedChannel, modeChannel; extern float rollChannel, pitchChannel, throttleChannel, yawChannel, armedChannel, modeChannel;
extern int wifiMode, udpLocalPort, udpRemotePort; extern int wifiMode, udpLocalPort, udpRemotePort;
extern float rcLossTimeout, descendTime;
Preferences storage; Preferences storage;
@@ -92,9 +91,6 @@ Parameter parameters[] = {
{"MAV_SYS_ID", &mavlinkSysId}, {"MAV_SYS_ID", &mavlinkSysId},
{"MAV_RATE_SLOW", &telemetrySlow.rate}, {"MAV_RATE_SLOW", &telemetrySlow.rate},
{"MAV_RATE_FAST", &telemetryFast.rate}, {"MAV_RATE_FAST", &telemetryFast.rate},
// safety
{"SF_RC_LOSS_TIME", &rcLossTimeout},
{"SF_DESCEND_TIME", &descendTime},
}; };
void setupParameters() { void setupParameters() {
@@ -125,7 +121,7 @@ float getParameter(int index) {
float getParameter(const char *name) { float getParameter(const char *name) {
for (auto &parameter : parameters) { for (auto &parameter : parameters) {
if (strcasecmp(parameter.name, name) == 0) { if (strcmp(parameter.name, name) == 0) {
return parameter.getValue(); return parameter.getValue();
} }
} }
@@ -134,7 +130,7 @@ float getParameter(const char *name) {
bool setParameter(const char *name, const float value) { bool setParameter(const char *name, const float value) {
for (auto &parameter : parameters) { for (auto &parameter : parameters) {
if (strcasecmp(parameter.name, name) == 0) { if (strcmp(parameter.name, name) == 0) {
if (parameter.integer && !isfinite(value)) return false; // can't set integer to NaN or Inf if (parameter.integer && !isfinite(value)) return false; // can't set integer to NaN or Inf
parameter.setValue(value); parameter.setValue(value);
return true; return true;

View File

@@ -6,21 +6,17 @@
#include <SBUS.h> #include <SBUS.h>
#include "util.h" #include "util.h"
#ifdef ESP32C3
SBUS rc(Serial1);
#else
SBUS rc(Serial2); SBUS rc(Serial2);
#endif
uint16_t channels[16]; // raw rc channels uint16_t channels[16]; // raw rc channels
float channelZero[16]; // calibration zero values float channelZero[16]; // calibration zero values
float channelMax[16]; // calibration max values float channelMax[16]; // calibration max values
float controlRoll, controlPitch, controlYaw, controlThrottle; // pilot's inputs, range [-1, 1] float controlRoll, controlPitch, controlYaw, controlThrottle; // pilot's inputs, range [-1, 1]
float controlMode = NAN; float controlMode = NAN; //
float controlTime = NAN; // time of the last controls update float controlTime; // time of the last controls update (0 when no RC)
// Channels mapping (nan means not assigned): // Channels mapping (using float to store in parameters):
float rollChannel = NAN, pitchChannel = NAN, throttleChannel = NAN, yawChannel = NAN, modeChannel = NAN; float rollChannel = NAN, pitchChannel = NAN, throttleChannel = NAN, yawChannel = NAN, modeChannel = NAN;
void setupRC() { void setupRC() {

View File

@@ -3,12 +3,12 @@
// Fail-safe functions // Fail-safe functions
#define RC_LOSS_TIMEOUT 1
#define DESCEND_TIME 10
extern float controlTime; extern float controlTime;
extern float controlRoll, controlPitch, controlThrottle, controlYaw; extern float controlRoll, controlPitch, controlThrottle, controlYaw;
float rcLossTimeout = 1;
float descendTime = 10;
void failsafe() { void failsafe() {
rcLossFailsafe(); rcLossFailsafe();
autoFailsafe(); autoFailsafe();
@@ -16,8 +16,9 @@ void failsafe() {
// RC loss failsafe // RC loss failsafe
void rcLossFailsafe() { void rcLossFailsafe() {
if (controlTime == 0) return; // no RC at all
if (!armed) return; if (!armed) return;
if (t - controlTime > rcLossTimeout) { if (t - controlTime > RC_LOSS_TIMEOUT) {
descend(); descend();
} }
} }
@@ -26,7 +27,7 @@ void rcLossFailsafe() {
void descend() { void descend() {
mode = AUTO; mode = AUTO;
attitudeTarget = Quaternion(); attitudeTarget = Quaternion();
thrustTarget -= dt / descendTime; thrustTarget -= dt / DESCEND_TIME;
if (thrustTarget < 0) { if (thrustTarget < 0) {
thrustTarget = 0; thrustTarget = 0;
armed = false; armed = false;

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2023 Oleg Kalachev <okalachev@gmail.com> // Copyright (c) 2023 Oleg Kalachev <okalachev@gmail.com>
// Repository: https://github.com/okalachev/flix // Repository: https://github.com/okalachev/flix
// Wi-Fi communication // Wi-Fi connectivity
#include <WiFi.h> #include <WiFi.h>
#include <WiFiAP.h> #include <WiFiAP.h>

View File

@@ -43,7 +43,6 @@ records = [record for record in records if record[0] != 0]
print(f'Received records: {len(records)}') print(f'Received records: {len(records)}')
os.makedirs(f'{DIR}/log', exist_ok=True)
log = open(f'{DIR}/log/{datetime.datetime.now().isoformat()}.csv', 'wb') log = open(f'{DIR}/log/{datetime.datetime.now().isoformat()}.csv', 'wb')
log.write(header.encode() + b'\n') log.write(header.encode() + b'\n')
for record in records: for record in records: