From 774144c43039e80ec3ed2b1e5f6190302ed6daff Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Thu, 6 Nov 2025 13:46:25 +0300 Subject: [PATCH] Many updates to documentation Updates to main readme. Add much more info to usage article. Move simulator building to simulation's readme. Improve assembly article. Many fixes. Updates in diagrams. --- README.md | 73 ++++++------- docs/assembly.md | 24 +++++ docs/book/firmware.md | 4 +- docs/build.md | 3 +- docs/firmware.md | 23 +++-- docs/img/control.svg | 3 +- docs/img/dataflow.svg | 3 +- docs/img/motor-tape.jpg | Bin 0 -> 62136 bytes docs/img/motors.svg | 89 ++++++++++++++++ docs/img/qgc-attitude.png | Bin 0 -> 15989 bytes docs/img/schematics1.svg | 2 +- docs/troubleshooting.md | 2 + docs/usage.md | 209 ++++++++++++++++---------------------- gazebo/README.md | 95 +++++++++++++++-- 14 files changed, 344 insertions(+), 186 deletions(-) mode change 120000 => 100644 docs/build.md create mode 100644 docs/img/motor-tape.jpg create mode 100644 docs/img/motors.svg create mode 100644 docs/img/qgc-attitude.png diff --git a/README.md b/README.md index a1d79fe..ef07d2f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Flix -**Flix** (*flight + X*) — making an open source ESP32-based quadcopter from scratch. +**Flix** (*flight + X*) — open source ESP32-based quadcopter made from scratch. @@ -52,25 +52,27 @@ The simulator is implemented using Gazebo and runs the original Arduino code: Flix simulator -## Articles +## Documentation * [Assembly instructions](docs/assembly.md). * [Usage: build, setup and flight](docs/usage.md). * [Troubleshooting](docs/troubleshooting.md). -* [Firmware architecture overview](docs/firmware.md). -* [Python library tutorial](tools/pyflix/README.md). +* [Simulation](gazebo/README.md). +* [Firmware architectural overview](docs/firmware.md). +* [Python library](tools/pyflix/README.md). * [Log analysis](docs/log.md). * [User builds gallery](docs/user.md). +* [Version 0 (obsolete)](docs/version0.md). ## Components |Type|Part|Image|Quantity| |-|-|:-:|:-:| |Microcontroller board|ESP32 Mini||1| -|IMU (and barometer²) board|GY‑91, MPU-9265 (or other MPU‑9250/MPU‑6500 board)
ICM20948V2 (ICM‑20948)³
GY-521 (MPU-6050)³⁻¹|

|1| -|Buck-boost converter (recommended)|To be determined, output 5V or 3.3V, see [user-contributed schematics](https://miro.com/app/board/uXjVN-dTjoo=/?moveToWidget=3458764612179508274&cot=14)||1| -|Motor|8520 3.7V brushed motor (shaft 0.8mm).
Motor with exact 3.7V voltage is needed, not ranged working voltage (3.7V — 6V).||4| -|Propeller|Hubsan 55 mm||4| +|IMU (and barometer¹) board|GY‑91, MPU-9265 (or other MPU‑9250/MPU‑6500 board)
ICM20948V2 (ICM‑20948)³
GY-521 (MPU-6050)³⁻¹|

|1| +|Boost converter (optional, for more stable power supply)|5V output||1| +|Motor|8520 3.7V brushed motor.
Motor with exact 3.7V voltage is needed, not ranged working voltage (3.7V — 6V).
Make sure the motor shaft diameter and propeller hole diameter match!||4| +|Propeller|55 mm (alternatively 65 mm)||4| |MOSFET (transistor)|100N03A or [analog](https://t.me/opensourcequadcopter/33)||4| |Pull-down resistor|10 kΩ||4| |3.7V Li-Po battery|LW 952540 (or any compatible by the size)||1| @@ -78,19 +80,17 @@ The simulator is implemented using Gazebo and runs the original Arduino code: |Li-Po Battery charger|Any||1| |Screws for IMU board mounting|M3x5||2| |Screws for frame assembly|M1.4x5||4| -|Frame main part|3D printed⁴:
[`flix-frame-1.1.stl`](docs/assets/flix-frame-1.1.stl) [`flix-frame-1.1.step`](docs/assets/flix-frame-1.1.step)
Recommended settings: layer 0.2 mm, line 0.4 mm, infill 100%.||1| +|Frame main part|3D printed²:
[`flix-frame-1.1.stl`](docs/assets/flix-frame-1.1.stl) [`flix-frame-1.1.step`](docs/assets/flix-frame-1.1.step)
Recommended settings: layer 0.2 mm, line 0.4 mm, infill 100%.||1| |Frame top part|3D printed:
[`esp32-holder.stl`](docs/assets/esp32-holder.stl) [`esp32-holder.step`](docs/assets/esp32-holder.step)||1| |Washer for IMU board mounting|3D printed:
[`washer-m3.stl`](docs/assets/washer-m3.stl) [`washer-m3.step`](docs/assets/washer-m3.step)||2| |Controller (recommended)|CC2500 transmitter, like BetaFPV LiteRadio CC2500 (RC receiver/Wi-Fi).
Two-sticks gamepad (Wi-Fi only) — see [recommended gamepads](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/joystick.html#supported-joysticks).
Other⁵||1| -|*RC receiver (optional)*|*DF500 or other⁵*||1| +|*RC receiver (optional)*|*DF500 or other³*||1| |Wires|28 AWG recommended||| |Tape, double-sided tape|||| -*² — barometer is not used for now.*
-*³ — change `MPU9250` to `ICM20948` or `MPU6050` in `imu.ino` file for using the appropriate boards.*
-*³⁻¹ — MPU-6050 supports I²C interface only (not recommended). To use it change IMU declaration to `MPU6050 IMU(Wire)`.*
-*⁴ — this frame is optimized for GY-91 board, if using other, the board mount holes positions should be modified.*
-*⁵ — you also may use any transmitter-receiver pair with SBUS interface.* +*¹ — barometer is not used for now.*
+*² — this frame is optimized for GY-91 board, if using other, the board mount holes positions should be modified.*
+*³ — you also may use any transmitter-receiver pair with SBUS interface.* Tools required for assembly: @@ -100,7 +100,7 @@ Tools required for assembly: * Screwdrivers. * Multimeter. -Feel free to modify the design and or code, and create your own improved versions of Flix! Send your results to the [official Telegram chat](https://t.me/opensourcequadcopterchat), or directly to the author ([E-mail](mailto:okalachev@gmail.com), [Telegram](https://t.me/okalachev)). +Feel free to modify the design and or code, and create your own improved versions. Send your results to the [official Telegram chat](https://t.me/opensourcequadcopterchat), or directly to the author ([E-mail](mailto:okalachev@gmail.com), [Telegram](https://t.me/okalachev)). ## Schematics @@ -108,7 +108,7 @@ Feel free to modify the design and or code, and create your own improved version Flix version 1 schematics -*(Dashed is optional).* +*(Dashed elements are optional).* Motor connection scheme: @@ -135,14 +135,15 @@ See [assembly guide](docs/assembly.md) for instructions on assembling the drone. * Solder pull-down resistors to the MOSFETs. * Connect the motors to the ESP32 Mini using MOSFETs, by following scheme: - |Motor|Position|Direction|Wires|GPIO| - |-|-|-|-|-| - |Motor 0|Rear left|Counter-clockwise|Black & White|GPIO12 (*TDI*)| - |Motor 1|Rear right|Clockwise|Blue & Red|GPIO13 (*TCK*)| - |Motor 2|Front right|Counter-clockwise|Black & White|GPIO14 (*TMS*)| - |Motor 3|Front left|Clockwise|Blue & Red|GPIO15 (*TD0*)| + |Motor|Position|Direction|Prop type|Motor wires|GPIO| + |-|-|-|-|-|-| + |Motor 0|Rear left|Counter-clockwise|B|Black & White|GPIO12 (*TDI*)| + |Motor 1|Rear right|Clockwise|A|Blue & Red|GPIO13 (*TCK*)| + |Motor 2|Front right|Counter-clockwise|B|Black & White|GPIO14 (*TMS*)| + |Motor 3|Front left|Clockwise|A|Blue & Red|GPIO15 (*TD0*)| - Counter-clockwise motors have black and white wires and clockwise motors have blue and red wires. + Clockwise motors have blue & red wires and correspond to propeller type A (marked on the propeller). + Counter-clockwise motors have black & white wires correspond to propeller type B. * Optionally connect the RC receiver to the ESP32's UART2: @@ -154,28 +155,14 @@ See [assembly guide](docs/assembly.md) for instructions on assembling the drone. *⁶ — UART2 RX pin was [changed](https://docs.espressif.com/projects/arduino-esp32/en/latest/migration_guides/2.x_to_3.0.html#id14) to GPIO4 in Arduino ESP32 core 3.0.* -### IMU placement +## Resources -Default IMU orientation in the code is **LFD** (Left-Forward-Down): - -GY-91 axes - -In case of using other IMU orientation, modify the `rotateIMU` function in the `imu.ino` file. - -See [FlixPeriph documentation](https://github.com/okalachev/flixperiph?tab=readme-ov-file#imu-axes-orientation) to learn axis orientation of other IMU boards. - -## Materials - -Subscribe to the Telegram channel on developing the drone and the flight controller (in Russian): https://t.me/opensourcequadcopter. - -Join the official Telegram chat: https://t.me/opensourcequadcopterchat. - -Detailed article on Habr.com about the development of the drone (in Russian): https://habr.com/ru/articles/814127/. - -See the information on the obsolete version 0 in the [corresponding article](docs/version0.md). +* Telegram channel on developing the drone and the flight controller (in Russian): https://t.me/opensourcequadcopter. +* Official Telegram chat: https://t.me/opensourcequadcopterchat. +* Detailed article on Habr.com about the development of the drone (in Russian): https://habr.com/ru/articles/814127/. ## Disclaimer -This is a fun DIY project, and I hope you find it interesting and useful. However, it's not easy to assemble and set up, and it's provided "as is" without any warranties. There’s no guarantee that it will work perfectly — or even work at all. +This is a DIY project, and I hope you find it interesting and useful. However, it's not easy to assemble and set up, and it's provided "as is" without any warranties. There's no guarantee that it will work perfectly, or even work at all. ⚠️ The author is not responsible for any damage, injury, or loss resulting from the use of this project. Use at your own risk! diff --git a/docs/assembly.md b/docs/assembly.md index ce0dd36..5f5d6d5 100644 --- a/docs/assembly.md +++ b/docs/assembly.md @@ -27,3 +27,27 @@ Soldered components ([schematics variant](https://miro.com/app/board/uXjVN-dTjoo
Assembled drone: + +## Motor directions + +> [!WARNING] +> The drone above is an early build, and it has **inversed** motor directions scheme. The photos only illustrate the assembly process in general. + +Use standard motor directions scheme: + + + +Motors connection table: + +|Motor|Position|Direction|Prop type|Motor wires|GPIO| +|-|-|-|-|-|-| +|Motor 0|Rear left|Counter-clockwise|B|Black & White|GPIO12 (*TDI*)| +|Motor 1|Rear right|Clockwise|A|Blue & Red|GPIO13 (*TCK*)| +|Motor 2|Front right|Counter-clockwise|B|Black & White|GPIO14 (*TMS*)| +|Motor 3|Front left|Clockwise|A|Blue & Red|GPIO15 (*TD0*)| + +## Motors tightening + +Motors should be installed very tightly — any vibration may lead to bad attitude estimation and unstable flight. If motors are loose, use tiny tape pieces to fix them tightly as shown below: + + diff --git a/docs/book/firmware.md b/docs/book/firmware.md index 7f36917..d9e04c6 100644 --- a/docs/book/firmware.md +++ b/docs/book/firmware.md @@ -12,8 +12,8 @@ * `acc` *(Vector)* — данные с акселерометра, *м/с2*. * `rates` *(Vector)* — отфильтрованные угловые скорости, *рад/с*. * `attitude` *(Quaternion)* — оценка ориентации (положения) дрона. -* `controlRoll`, `controlPitch`, ... *(float[])* — команды управления от пилота, в диапазоне [-1, 1]. -* `motors` *(float[])* — выходные сигналы на моторы, в диапазоне [0, 1]. +* `controlRoll`, `controlPitch`, `controlYaw`, `controlThrottle`, `controlMode` *(float)* — команды управления от пилота, в диапазоне [-1, 1]. +* `motors` *(float[4])* — выходные сигналы на моторы, в диапазоне [0, 1]. ## Исходные файлы diff --git a/docs/build.md b/docs/build.md deleted file mode 120000 index d59366e..0000000 --- a/docs/build.md +++ /dev/null @@ -1 +0,0 @@ -usage.md \ No newline at end of file diff --git a/docs/build.md b/docs/build.md new file mode 100644 index 0000000..c70ba7c --- /dev/null +++ b/docs/build.md @@ -0,0 +1,2 @@ + +Build instructions are moved to [usage article](usage.md). diff --git a/docs/firmware.md b/docs/firmware.md index 4ad0523..337ebeb 100644 --- a/docs/firmware.md +++ b/docs/firmware.md @@ -6,7 +6,7 @@ The firmware is a regular Arduino sketch, and it follows the classic Arduino one Firmware dataflow diagram -The main loop is running at 1000 Hz. All the dataflow goes through global variables (for simplicity): +The main loop is running at 1000 Hz. The dataflow goes through global variables, including: * `t` *(float)* — current step time, *s*. * `dt` *(float)* — time delta between the current and previous steps, *s*. @@ -14,12 +14,12 @@ The main loop is running at 1000 Hz. All the dataflow goes through global variab * `acc` *(Vector)* — acceleration data from the accelerometer, *m/s2*. * `rates` *(Vector)* — filtered angular rates, *rad/s*. * `attitude` *(Quaternion)* — estimated attitude (orientation) of drone. -* `controlRoll`, `controlPitch`, ... *(float[])* — pilot control inputs, range [-1, 1]. -* `motors` *(float[])* — motor outputs, range [0, 1]. +* `controlRoll`, `controlPitch`, `controlYaw`, `controlThrottle`, `controlMode` *(float)* — pilot control inputs, range [-1, 1]. +* `motors` *(float[4])* — motor outputs, range [0, 1]. ## Source files -Firmware source files are located in `flix` directory. The core files are: +Firmware source files are located in `flix` directory. * [`flix.ino`](../flix/flix.ino) — Arduino sketch main file, entry point.Includes some global variable definitions and the main loop. * [`imu.ino`](../flix/imu.ino) — reading data from the IMU sensor (gyroscope and accelerometer), IMU calibration. @@ -28,6 +28,7 @@ Firmware source files are located in `flix` directory. The core files are: * [`control.ino`](../flix/control.ino) — control subsystem, three-dimensional two-level cascade PID controller. * [`motors.ino`](../flix/motors.ino) — PWM motor output control. * [`mavlink.ino`](../flix/mavlink.ino) — interaction with QGroundControl or [pyflix](../tools/pyflix) via MAVLink protocol. +* [`cli.ino`](../flix/cli.ino) — serial and MAVLink console. Utility files: @@ -45,12 +46,22 @@ Pilot inputs are interpreted in `interpretControls()`, and then converted to the * `torqueTarget` *(Vector)* — target torque, range [-1, 1]. * `thrustTarget` *(float)* — collective thrust target, range [0, 1]. -Control command is processed in `controlAttitude()`, `controlRates()`, `controlTorque()` functions. Each function may be skipped if the corresponding target is set to `NAN`. +Control command is handled in `controlAttitude()`, `controlRates()`, `controlTorque()` functions. Each function may be skipped if the corresponding control target is set to `NAN`. Control subsystem diagram Armed state is stored in `armed` variable, and current mode is stored in `mode` variable. -## Building +### Console + +To write into the console, `print()` function is used. This function sends data both to the Serial console and to the MAVLink console (which can be accessed wirelessly in QGroundControl). The function supports formatting: + +```cpp +print("Test value: %.2f\n", testValue); +``` + +In order to add a console command, modify the `doCommand()` function in `cli.ino` file. + +## Building the firmware See build instructions in [usage.md](usage.md). diff --git a/docs/img/control.svg b/docs/img/control.svg index 79abe53..e5d9785 100644 --- a/docs/img/control.svg +++ b/docs/img/control.svg @@ -1,4 +1,3 @@ - -
interpretControls
controlThottle, controlYaw
controlRoll, controlPitch
controlMode
controlAttitude
controlRates
controlTorque
attitudeTarget, ratesExtra
ratesTarget
torqueTarget
thrustTarget
motors[]
in ACRO mode
\ No newline at end of file +
interpretControls
interpretControls
controlThottle, controlYaw
controlRoll, controlPitch
controlMode
controlThottle, controlYaw...
controlAttitude
controlAttitude
controlRates
controlRates
controlTorque
controlTorque
attitudeTarget, ratesExtra
attitudeTarget, ratesExtra
ratesTarget
ratesTarget
torqueTarget
torqueTarget
thrustTarget
thrustTarget
motors[]
motors[]
in ACRO mode
in ACRO mode
\ No newline at end of file diff --git a/docs/img/dataflow.svg b/docs/img/dataflow.svg index a2c545a..7c7c98d 100644 --- a/docs/img/dataflow.svg +++ b/docs/img/dataflow.svg @@ -1,4 +1,3 @@ - -
gyro, acc
estimate.ino
control.ino
rc.ino
motors.ino
rates, attitude
controlRoll, controlPitch, ...
motors[]
feedback
\ No newline at end of file +imu.ino
gyro, acc
gyro, acc
estimate.ino
estimate.ino
control.ino
control.ino
rc.ino
rc.ino
motors.ino
motors.ino
rates, attitude
rates, attitude
controlRoll, controlPitch,
controlYaw, controlThrottle,
controlMode
controlRoll, controlPitch,...
motors[]
motors[]
feedback
feedback
\ No newline at end of file diff --git a/docs/img/motor-tape.jpg b/docs/img/motor-tape.jpg new file mode 100644 index 0000000000000000000000000000000000000000..77bf7dd3f731089f1764681c25ce0829eeeff7d9 GIT binary patch literal 62136 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 VbDza-^or^LQ7v5ZYt_%G{{bPcxyb+k literal 0 HcmV?d00001 diff --git a/docs/img/motors.svg b/docs/img/motors.svg new file mode 100644 index 0000000..949736f --- /dev/null +++ b/docs/img/motors.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + 0 + 1 + 2 + prop A + prop A + prop B + prop B + + diff --git a/docs/img/qgc-attitude.png b/docs/img/qgc-attitude.png new file mode 100644 index 0000000000000000000000000000000000000000..b672a8bcca3ce48d3d5d385519a3e2d8cc8aad37 GIT binary patch literal 15989 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 -
ESP32
ESP32
Battery
Battery
IMU
IMU
MOSFET x4
MOSFET x4
Motors x4
Motors x4
RC Receiver
RC Receiver
SPI
SPI
PWM
PWM
PWM
PWM
SBUS (UART)
SBUS (UART)
≈3.7V
≈3.7V
Buck-Boost
Buck-Boost
≈3.7V
≈3.7V
3.3V / 5V
3.3V / 5V
\ No newline at end of file +
ESP32
ESP32
Battery
Battery
IMU
IMU
MOSFET x4
MOSFET x4
Motors x4
Motors x4
RC Receiver
RC Receiver
SPI
SPI
PWM
PWM
PWM
PWM
SBUS (UART)
SBUS (UART)
≈3.7V
≈3.7V
Boost
Boost
≈3.7V
≈3.7V
5V
5V
\ No newline at end of file diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 509fd11..2b2554d 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -32,6 +32,8 @@ Do the following: * `mfl` — should rotate front left motor (clockwise). * `mrl` — should rotate rear left motor (counter-clockwise). * `mrr` — should rotate rear right motor (clockwise). +* **Check the propeller directions are correct**. Make sure your propeller types (A or B) are installed as on the picture: + * **Check the remote control**. Using `rc` command, check the control values reflect your sticks movement. All the controls should change between -1 and 1, and throttle between 0 and 1. * If using SBUS receiver, **calibrate the RC**. Type `cr` command in Serial Monitor and follow the instructions. * **Check the IMU output using QGroundControl**. Connect to the drone using QGroundControl on your computer. Go to the *Analyze* tab, *MAVLINK Inspector*. Plot the data from the `SCALED_IMU` message. The gyroscope and accelerometer data should change according to the drone movement. diff --git a/docs/usage.md b/docs/usage.md index e6267a2..437cc37 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -1,130 +1,36 @@ # Usage: build, setup and flight -To use Flix, you need to build the firmware and upload it to the ESP32 board. For simulation, you need to build and run the simulator. +To fly Flix quadcopter, you need to build the firmware, upload it to the ESP32 board, and set up the drone for flight. -For the start, clone the repository using git: +To get the firmware sources, clone the repository using git: ```bash -git clone https://github.com/okalachev/flix.git -cd flix +git clone https://github.com/okalachev/flix.git && cd flix ``` -## Simulation +Beginners can [download the source code as a ZIP archive](https://github.com/okalachev/flix/archive/refs/heads/master.zip). -### Ubuntu +## Building the firmware -The latest version of Ubuntu supported by Gazebo 11 simulator is 20.04. If you have a newer version, consider using a virtual machine. - -1. Install Arduino CLI: - - ```bash - curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh - ``` - -2. Install Gazebo 11: - - ```bash - sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list' - wget https://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add - - sudo apt-get update - sudo apt-get install -y gazebo11 libgazebo11-dev - ``` - - Set up your Gazebo environment variables: - - ```bash - echo "source /usr/share/gazebo/setup.sh" >> ~/.bashrc - source ~/.bashrc - ``` - -3. Install SDL2 and other dependencies: - - ```bash - sudo apt-get update && sudo apt-get install build-essential libsdl2-dev - ``` - -4. Add your user to the `input` group to enable joystick support (you need to re-login after this command): - - ```bash - sudo usermod -a -G input $USER - ``` - -5. Run the simulation: - - ```bash - make simulator - ``` - -### macOS - -1. Install Homebrew package manager, if you don't have it installed: - - ```bash - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - ``` - -2. Install Arduino CLI, Gazebo 11 and SDL2: - - ```bash - brew tap osrf/simulation - brew install arduino-cli - brew install gazebo11 - brew install sdl2 - ``` - - Set up your Gazebo environment variables: - - ```bash - echo "source /opt/homebrew/share/gazebo/setup.sh" >> ~/.zshrc - source ~/.zshrc - ``` - -3. Run the simulation: - - ```bash - make simulator - ``` - -### Setup - -#### Control with smartphone - -1. Install [QGroundControl mobile app](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html#android) on your smartphone. For **iOS**, use [QGroundControl build from TAJISOFT](https://apps.apple.com/ru/app/qgc-from-tajisoft/id1618653051). -2. Connect your smartphone to the same Wi-Fi network as the machine running the simulator. -3. If you're using a virtual machine, make sure that its network is set to the **bridged** mode with Wi-Fi adapter selected. -4. Run the simulation. -5. Open QGroundControl app. It should connect and begin showing the virtual drone's telemetry automatically. -6. Go to the settings and enable *Virtual Joystick*. *Auto-Center Throttle* setting **should be disabled**. -7. Use the virtual joystick to fly the drone! - -#### Control with USB remote control - -1. Connect your USB remote control to the machine running the simulator. -2. Run the simulation. -3. Calibrate the RC using `cr` command in the command line interface. -4. Run the simulation again. -5. Use the USB remote control to fly the drone! - -## Firmware +You can build and upload the firmware using either **Arduino IDE** (easier for beginners) or a **command line**. ### Arduino IDE (Windows, Linux, macOS) 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.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): * `FlixPeriph`, the latest version. * `MAVLink`, version 2.0.16. -5. Clone the project using git or [download the source code as a ZIP archive](https://codeload.github.com/okalachev/flix/zip/refs/heads/master). -6. Open the downloaded Arduino sketch `flix/flix.ino` in Arduino IDE. -7. 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. -8. [Build and upload](https://docs.arduino.cc/software/ide-v2/tutorials/getting-started/ide-v2-uploading-a-sketch) the firmware using 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. +7. [Build and upload](https://docs.arduino.cc/software/ide-v2/tutorials/getting-started/ide-v2-uploading-a-sketch) the firmware using Arduino IDE. ### Command line (Windows, Linux, macOS) 1. [Install Arduino CLI](https://arduino.github.io/arduino-cli/installation/). - On Linux, use: + On Linux, install it like this: ```bash curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh @@ -149,19 +55,84 @@ The latest version of Ubuntu supported by Gazebo 11 simulator is 20.04. If you h make upload monitor ``` -See other available Make commands in the [Makefile](../Makefile). +See other available Make commands in [Makefile](../Makefile). > [!TIP] -> You can test the firmware on a bare ESP32 board without connecting IMU and other peripherals. The Wi-Fi network `flix` should appear and all the basic functionality including CLI and QGroundControl connection should work. +> You can test the firmware on a bare ESP32 board without connecting IMU and other peripherals. The Wi-Fi network `flix` should appear and all the basic functionality including console and QGroundControl connection should work. -### Setup +## Before first flight + +### Choose the IMU model + +In case if using different IMU model than MPU9250, change `imu` variable declaration in the `imu.ino`: + +```cpp +ICM20948 imu(SPI); // For ICM-20948 +MPU6050 imu(Wire); // For MPU-6050 +``` + +### Setup the IMU orientation + +The IMU orientation is defined in `rotateIMU` function in the `imu.ino` file. Change it so it converts the IMU axes to the drone's axes correctly. **Drone axes are X forward, Y left, Z up.** + +See various [IMU axes orientations table](https://github.com/okalachev/flixperiph/?tab=readme-ov-file#imu-axes-orientation) to help you set up the correct orientation. + +### Connect using QGroundControl + +QGroundControl is a ground control station software that can be used to monitor and control the drone. + +1. Install mobile or desktop version of [QGroundControl](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html). +2. Power up the drone. +3. Connect your computer or smartphone to the appeared `flix` Wi-Fi network (password: `flixwifi`). +4. Launch QGroundControl app. It should connect and begin showing the drone's telemetry automatically + +### Access console + +The console is a command line interface (CLI) that allows to interact with the drone, change parameters, and perform various actions. There are two ways of accessing the console: using **serial port** or using **QGroundControl (wirelessly)**. + +To access the console using serial port: + +1. Connect the ESP32 board to the computer using USB cable. +2. Open Serial Monitor in Arduino IDE (or use `make monitor` command in the command line). +3. In Arduino IDE, make sure the baudrate is set to 115200. + +To access the console wirelessly using QGroundControl: + +1. Connect to the drone using QGroundControl app. +2. Go to the QGroundControl menu ⇒ *Vehicle Setup* ⇒ *Analyze Tools* ⇒ *MAVLink Console*. + + +Use `help` command to see the list of available commands. + +### Calibrate accelerometer Before flight you need to calibrate the accelerometer: -1. Open Serial Monitor in Arduino IDE (or use `make monitor` command in the command line). +1. Access the console using QGroundControl (more convenient) or Serial Monitor. 2. Type `ca` command there and follow the instructions. -#### Control with smartphone +### Check everything works + +1. Check the IMU is working: perform `imu` command and check its output: + * The `status` field should be `OK`. + * The `rate` field should be about 1000 (Hz). + * The `accel` and `gyro` fields should change as you move the drone. + +2. Check the attitude estimation: connect to the drone using QGroundControl, rotate the drone in different orientations and check if the attitude estimation shown in QGroundControl is correct. Attitude indicator in QGroundControl is shown below: + + + +3. Perform motor tests in the console. **Remove the propellers before this!** Use the following commands: + * `mfr` — should rotate front right motor (counter-clockwise). + * `mfl` — should rotate front left motor (clockwise). + * `mrl` — should rotate rear left motor (counter-clockwise). + * `mrr` — should rotate rear right motor (clockwise). + +## Setup remote control + +There are several ways to control the drone's flight: using **smartphone** (Wi-Fi), using **standard radio remote control**, or using **USB remote control** (Wi-Fi). + +### Control with smartphone 1. Install [QGroundControl mobile app](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html#android) on your smartphone. 2. Power the drone using the battery. @@ -173,7 +144,7 @@ Before flight you need to calibrate the accelerometer: > [!TIP] > Decrease `TILT_MAX` parameter when flying using the smartphone to make the controls less sensitive. -#### Control with remote control +### Control with remote control Before flight using remote control, you need to calibrate it: @@ -181,7 +152,7 @@ Before flight using remote control, you need to calibrate it: 2. Type `cr` command there and follow the instructions. 3. Use the remote control to fly the drone! -#### Control with USB remote control (Wi-Fi) +### Control with USB remote control If your drone doesn't have RC receiver installed, you can use USB remote control and QGroundControl app to fly it. @@ -193,9 +164,6 @@ If your drone doesn't have RC receiver installed, you can use USB remote control 6. Go the the QGroundControl menu ⇒ *Vehicle Setup* ⇒ *Joystick*. Calibrate you USB remote control there. 7. Use the USB remote control to fly the drone! -> [!NOTE] -> If something goes wrong, go to the [Troubleshooting](troubleshooting.md) article. - ## Flight For both virtual sticks and a physical joystick, the default control scheme is left stick for throttle and yaw and right stick for pitch and roll: @@ -214,6 +182,9 @@ When finished flying, **disarm** the drone, moving the left stick to the bottom +> [!NOTE] +> If something goes wrong, go to the [Troubleshooting](troubleshooting.md) article. + ### Flight modes Flight mode is changed using mode switch on the remote control or using the command line. @@ -241,12 +212,6 @@ If the pilot moves the control sticks, the drone will switch back to *STAB* mode ## Adjusting parameters -You can adjust some of the drone's parameters (include PID coefficients) in QGroundControl app. In order to do that, go to the QGroundControl menu ⇒ *Vehicle Setup* ⇒ *Parameters*. +You can adjust some of the drone's parameters (include PID coefficients) in QGroundControl. In order to do that, go to the QGroundControl menu ⇒ *Vehicle Setup* ⇒ *Parameters*. - -## CLI access - -In addition to accessing the drone's command line interface (CLI) using the serial port, you can also access it with QGroundControl using Wi-Fi connection. To do that, go to the QGroundControl menu ⇒ *Vehicle Setup* ⇒ *Analyze Tools* ⇒ *MAVLink Console*. - - diff --git a/gazebo/README.md b/gazebo/README.md index c7e2608..bce4980 100644 --- a/gazebo/README.md +++ b/gazebo/README.md @@ -1,15 +1,96 @@ -# Gazebo Simulation +# Simulation -Flix simulator +The Flix drone simulator is based on Gazebo 11 and runs the firmware code in virtual physical environment. -## Building and running +Gazebo 11 works on **Ubuntu 20.04** and used to work on macOS. However, on the recent macOS versions it seems to be broken, so Ubuntu 20.04 is recommended. -See [building and running instructions](../docs/usage.md#simulation). +Flix simulator + +## Installation + +1. Clone the Flix repository using it: + + ```bash + git clone https://github.com/okalachev/flix.git && cd flix + ``` + +2. Install Arduino CLI: + + ```bash + curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh + ``` + +3. Install Gazebo 11: + + ```bash + sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list' + wget https://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add - + sudo apt-get update + sudo apt-get install -y gazebo11 libgazebo11-dev + ``` + + Set up your Gazebo environment variables: + + ```bash + echo "source /usr/share/gazebo/setup.sh" >> ~/.bashrc + source ~/.bashrc + ``` + +4. Install SDL2 and other dependencies: + + ```bash + sudo apt-get update && sudo apt-get install build-essential libsdl2-dev + ``` + +5. Add your user to the `input` group to enable joystick support (you need to re-login after this command): + + ```bash + sudo usermod -a -G input $USER + ``` + +6. Run the simulation: + + ```bash + make simulator + ``` + +## Usage + +Just like the real drone, the simulator can be controlled using a USB remote control or a smartphone. + +### Control with smartphone + +1. Install [QGroundControl mobile app](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html#android) on your smartphone. For **iOS**, use [QGroundControl build from TAJISOFT](https://apps.apple.com/ru/app/qgc-from-tajisoft/id1618653051). +2. Connect your smartphone to the same Wi-Fi network as the machine running the simulator. +3. If you're using a virtual machine, make sure that its network is set to the **bridged** mode with Wi-Fi adapter selected. +4. Run the simulation. +5. Open QGroundControl app. It should connect and begin showing the virtual drone's telemetry automatically. +6. Go to the settings and enable *Virtual Joystick*. *Auto-Center Throttle* setting **should be disabled**. +7. Use the virtual joystick to fly the drone! + +### Control with USB remote control + +1. Connect your USB remote control to the machine running the simulator. +2. Run the simulation. +3. Calibrate the RC using `cr` command in the command line interface. +4. Use the USB remote control to fly the drone! + +### Piloting + +To start the flight, arm the drone moving the throttle stick to the bottom right position: + + + +To disarm, move the throttle stick to the bottom left position: + + + +See other piloting and usage details in general [usage article](../docs/usage.md). ## Code structure -Flix simulator is based on [Gazebo Classic](https://classic.gazebosim.org) and consists of the following components: +Flix simulator consists of the following components: -* Physical model of the drone: [`models/flix/flix.sdf`](models/flix/flix.sdf). +* Physical model of the drone in Gazebo format: [`models/flix/flix.sdf`](models/flix/flix.sdf). * Plugin for Gazebo: [`simulator.cpp`](simulator.cpp). The plugin is attached to the physical model. It receives stick positions from the controller, gets the data from the virtual sensors, and then passes this data to the Arduino code. -* Arduino imitation: [`Arduino.h`](Arduino.h). This file contains partial implementation of the Arduino API, that is working within Gazebo plugin environment. +* Arduino emulation: [`Arduino.h`](Arduino.h). This file contains partial implementation of the Arduino API, that is working within Gazebo plugin environment.