From 65cedc8bf8f315a67080745a46f33148b4ed4c5c Mon Sep 17 00:00:00 2001 From: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:38:30 -0900 Subject: [PATCH 01/71] px_uploader: add ARK PID/VIDs (#26358) --- Tools/px4_uploader.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tools/px4_uploader.py b/Tools/px4_uploader.py index 8da12e32ba..3b54950747 100755 --- a/Tools/px4_uploader.py +++ b/Tools/px4_uploader.py @@ -259,6 +259,9 @@ PX4_USB_IDS: list[tuple[int, int, str]] = [ (0x0483, 0x5740, "STMicroelectronics Virtual COM Port"), # Generic ST bootloader (0x1209, 0x5740, "Generic STM32"), (0x1209, 0x5741, "ArduPilot"), + (0x3185, 0x0039, "ARK FMU v6x"), + (0x3185, 0x003A, "ARK Pi6x"), + (0x3185, 0x003B, "ARK FPV"), (0x2341, 0x8036, "Arduino Leonardo"), # Some PX4 boards use this ] From c90095e8b42ae28289e6f5d328793f275f1d4ffd Mon Sep 17 00:00:00 2001 From: PX4 Build Bot Date: Wed, 28 Jan 2026 16:43:18 +1100 Subject: [PATCH 02/71] New Crowdin translations - zh-CN (#26248) Co-authored-by: Crowdin Bot --- docs/zh/SUMMARY.md | 12 +- docs/zh/advanced/gimbal_control.md | 2 +- docs/zh/advanced/neural_networks.md | 120 +--------- docs/zh/can/index.md | 4 + docs/zh/config/safety.md | 26 +-- docs/zh/debug/asset_tracking.md | 68 ++++++ docs/zh/dronecan/ark_g5_rtk_gps.md | 112 +++++++++ docs/zh/dronecan/ark_g5_rtk_heading_gps.md | 150 ++++++++++++ docs/zh/dronecan/index.md | 2 + docs/zh/features_fw/gain_compression.md | 2 +- docs/zh/flight_controller/micoair743-lite.md | 2 +- docs/zh/flight_controller/radiolink_pix6.md | 2 +- docs/zh/flight_controller/x-mav_ap-h743r1.md | 4 +- docs/zh/flight_modes_fw/hold.md | 77 +++++- docs/zh/flight_modes_fw/takeoff.md | 4 +- docs/zh/gps_compass/rtk_gps.md | 88 +++---- docs/zh/hardware/porting_guide.md | 6 +- docs/zh/middleware/uxrce_dds.md | 6 +- docs/zh/neural_networks/index.md | 21 ++ .../mc_neural_network_control.md | 119 ++++++++++ .../zh/neural_networks/nn_module_utilities.md | 86 +++++++ docs/zh/neural_networks/raptor.md | 221 ++++++++++++++++++ docs/zh/neural_networks/tflm.md | 77 ++++++ docs/zh/releases/1.16.md | 1 + docs/zh/releases/1.17.md | 134 +++++++++++ docs/zh/releases/index.md | 3 +- docs/zh/releases/main.md | 36 ++- docs/zh/ros2/px4_ros2_control_interface.md | 10 +- docs/zh/sim_sih/index.md | 4 +- 29 files changed, 1186 insertions(+), 213 deletions(-) create mode 100644 docs/zh/debug/asset_tracking.md create mode 100644 docs/zh/dronecan/ark_g5_rtk_gps.md create mode 100644 docs/zh/dronecan/ark_g5_rtk_heading_gps.md create mode 100644 docs/zh/neural_networks/index.md create mode 100644 docs/zh/neural_networks/mc_neural_network_control.md create mode 100644 docs/zh/neural_networks/nn_module_utilities.md create mode 100644 docs/zh/neural_networks/raptor.md create mode 100644 docs/zh/neural_networks/tflm.md create mode 100644 docs/zh/releases/1.17.md diff --git a/docs/zh/SUMMARY.md b/docs/zh/SUMMARY.md index 2eead55cb5..440ee6c682 100644 --- a/docs/zh/SUMMARY.md +++ b/docs/zh/SUMMARY.md @@ -128,6 +128,7 @@ - [LED灯含义](getting_started/led_meanings.md) - [声调/声音含义](getting_started/tunes.md) - [QGroundControl Flight-Readiness Status](flying/pre_flight_checks.md) + - [Asset Tracking](debug/asset_tracking.md) - [Hardware Selection & Setup](hardware/drone_parts.md) - [飞行控制器(Autopilots)](flight_controller/index.md) @@ -273,6 +274,8 @@ - [Holybro M8N & M9N GPS](gps_compass/gps_holybro_m8n_m9n.md) - [Sky-Drones SmartAP GPS](gps_compass/gps_smartap.md) - [RTK GNSS](gps_compass/rtk_gps.md) + - [ARK G5 RTK GPS](dronecan/ark_g5_rtk_gps.md) + - [ARK G5 RTK HEADING GPS](dronecan/ark_g5_rtk_heading_gps.md) - [ARK RTK GPS (CAN)](dronecan/ark_rtk_gps.md) - [ARK RTK GPS L1 L5 (CAN)](dronecan/ark_rtk_gps_l1_l2.md) - [ARK X20 RTK GPS (CAN)](dronecan/ark_x20_rtk_gps.md) @@ -840,9 +843,11 @@ - [Camera Integration/Architecture](camera/camera_architecture.md) - [机器视觉](advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](tutorials/motion-capture.md) - - [Neural Networks](advanced/neural_networks.md) - - [Neural Network Module Utilities](advanced/nn_module_utilities.md) - - [TensorFlow Lite Micro (TFLM)](advanced/tflm.md) + - [Neural Networks](neural_networks/index.md) + - [MC NN Control Module (Generic)](neural_networks/mc_neural_network_control.md) + - [Neural Network Module Utilities](neural_networks/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](neural_networks/tflm.md) + - [RAPTOR Adaptive RL NN Module](neural_networks/raptor.md) - [安装英特尔 RealSense R200 的驱动程序](advanced/realsense_intel_driver.md) - [切换状态估计器](advanced/switching_state_estimators.md) - [外部模块](advanced/out_of_tree_modules.md) @@ -925,6 +930,7 @@ - [版本发布](releases/index.md) - [main (alpha)](releases/main.md) + - [1.17 (alpha)](releases/1.17.md) - [1.16 (stable)](releases/1.16.md) - [1.15](releases/1.15.md) - [1.14](releases/1.14.md) diff --git a/docs/zh/advanced/gimbal_control.md b/docs/zh/advanced/gimbal_control.md index aa7fe7ad8c..234dfcd2ff 100644 --- a/docs/zh/advanced/gimbal_control.md +++ b/docs/zh/advanced/gimbal_control.md @@ -74,7 +74,7 @@ The output pins that are used to control the gimbal are set in the [Acuator Conf ![Gimbal Actuator config](../../assets/config/actuators/qgc_actuators_gimbal.png) -The PWM values to use for the disarmed, maximum and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low and high position in the slider. +The PWM values to use for the disarmed, maximum, center and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low, center and high position in the slider. 这些数值也可以在云台文档中提供。 ## Gimbal Control in Missions diff --git a/docs/zh/advanced/neural_networks.md b/docs/zh/advanced/neural_networks.md index 90d45301c3..039259fd5f 100644 --- a/docs/zh/advanced/neural_networks.md +++ b/docs/zh/advanced/neural_networks.md @@ -1,119 +1 @@ -# Neural Networks - - - -:::warning -This is an experimental module. -Use at your own risk. -::: - -The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. -It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. - -The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md) module. -The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. -While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. -Note that after training the network you will need to update and rebuild PX4. - -TLFM is a mature inference library intended for use on embedded devices. -It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. -If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). - -This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. -The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. - -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). - -## Neural Network PX4 Firmware - -:::warning -This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). -::: - -The module has been tested on a number of configurations, which can be build locally using the commands: - -```sh -make px4_sitl_neural -``` - -```sh -make px4_fmu-v6c_neural -``` - -```sh -make mro_pixracerpro_neural -``` - -You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: - -```sh -CONFIG_LIB_TFLM=y -CONFIG_MODULES_MC_NN_CONTROL=y -``` - -:::tip -The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. -::: - -## Example Module Overview - -The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: - -![neural_control](../../assets/advanced/neural_control.png) - -In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. -We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. -We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) - -### Input - -The input can be changed to whatever you want. -Set up the input you want to use during training and then provide the same input in PX4. -In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: - -- [3] Local position error. (goal position - current position) -- [6] The first 2 rows of a 3 dimensional rotation matrix. -- [3] Linear velocity -- [3] Angular velocity - -All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. -PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. -Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. - -![ENU-NED](../../assets/advanced/ENU-NED.png) - -ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. - -### 输出 - -The output consists of 4 values, the motor forces, one for each motor. -These are transformed in the `RescaleActions()` function. -This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. -So the output from the network needs to be normalized before they can be sent to the motors in PX4. - -The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. -The publishing is handled in `PublishOutput(float* command_actions)` function. - -:::tip -If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. -Decrease it for more thrust. -::: - -## Training your own Network - -The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). -But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. - -Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. -If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). - -You should do one system identification flight for this and get an approximate inertia matrix for your platform. -On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). - -Then do the following steps: - -- Do a hover flight -- Read of the logs what RPM is required for the drone to hover. -- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. -- Insert these values into the Aerial Gym configuration and train your network. -- Convert the network as explained in [TFLM](tflm.md). + diff --git a/docs/zh/can/index.md b/docs/zh/can/index.md index 50757f6643..452f0aba97 100644 --- a/docs/zh/can/index.md +++ b/docs/zh/can/index.md @@ -10,6 +10,10 @@ CAN it is designed to be democratic and uses differential signaling. For this reason it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. CAN 还允许来自外设的状态反馈,并通过总线方便的进行固件升级。 +PX4 has the ability to track and log detailed information from CAN devices, including firmware versions, hardware versions, and serial numbers. +This enables unique identification and lifecycle tracking of hardware connected to the flight controller. +See [Asset Tracking](../debug/asset_tracking.md) for more information. + PX4 支持与 CAN 设备通信的两个软件协议: - [DroneCAN](../dronecan/index.md): PX4 推荐大多数常见的设置。 diff --git a/docs/zh/config/safety.md b/docs/zh/config/safety.md index 6929365518..8e7ea70b1d 100644 --- a/docs/zh/config/safety.md +++ b/docs/zh/config/safety.md @@ -121,36 +121,32 @@ PX4 and the receiver may also need to be configured in order to _detect RC loss_ ![Safety - RC Loss (QGC)](../../assets/qgc/setup/safety/safety_rc_loss.png) -The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [RC Loss timeout](#COM_RC_LOSS_T). -Users that want to disable the RC loss failsafe in specific automatic modes (mission, hold, offboard) can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). +The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [manual control loss timeout](#COM_RC_LOSS_T). +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). Additional (and underlying) parameter settings are shown below. | 参数 | 设置 | 描述 | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Manual Control Loss Timeout | Time after last setpoint received from the selected manual control source after which manual control is considered lost. This must be kept short because the vehicle will continue to fly using the old manual control setpoint until the timeout triggers. | +| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Manual Control Loss Timeout | Time after last setpoint received from the selected manual control source after which manual control is considered lost. This must be kept short because the vehicle will continue to fly using the last known stick position until the timeout triggers. | | [COM_FAIL_ACT_T](../advanced_config/parameter_reference.md#COM_FAIL_ACT_T) | Failsafe Reaction Delay | Delay in seconds between failsafe condition being triggered (`COM_RC_LOSS_T`) and failsafe action (RTL, Land, Hold). In this state the vehicle waits in hold mode for the manual control source to reconnect. This might be set longer for long-range flights so that intermittent connection loss doesn't immediately invoke the failsafe. It can be to zero so that the failsafe triggers immediately. | | [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | 故障保护动作 | Disabled, Loiter, Return, Land, Disarm, Terminate. | -| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC Loss Exceptions | Set the modes in which manual control loss is ignored: Mission, Hold, Offboard. | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC Loss Exceptions | Set modes in which manual control loss is ignored. | ## 数据链路丢失故障保护 -The Data Link Loss failsafe is triggered if a telemetry link (connection to ground station) is lost. +The Data Link Loss failsafe is triggered if the connection to the last MAVLink ground station like QGroundControl is lost. +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_DLL_EXCEPT](#COM_DLL_EXCEPT). ![Safety - Data Link Loss (QGC)](../../assets/qgc/setup/safety/safety_data_link_loss.png) The settings and underlying parameters are shown below. -| 设置 | 参数 | 描述 | -| -------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -| 数据链路丢失超时 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 数据连接断开后到故障保护触发之前的时间。 | -| 故障保护动作 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | - -The following settings also apply, but are not displayed in the QGC UI. - -| 设置 | 参数 | 描述 | -| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes where DL loss will not trigger a failsafe. | +| 设置 | 参数 | 描述 | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| 数据链路丢失超时 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 数据连接断开后到故障保护触发之前的时间。 | +| 故障保护动作 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | +| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes in which data link loss is ignored. | ## 地理围栏故障保护 diff --git a/docs/zh/debug/asset_tracking.md b/docs/zh/debug/asset_tracking.md new file mode 100644 index 0000000000..c4bcdda67a --- /dev/null +++ b/docs/zh/debug/asset_tracking.md @@ -0,0 +1,68 @@ +# Asset Tracking + + + +PX4 can track and log detailed information about external hardware devices connected to the flight controller. +This enables unique identification of vehicle parts throughout their operational lifetime using device IDs, serial numbers, and version information. + +:::info +Asset tracking is currently implemented for [DroneCAN](../dronecan/index.md) devices only. +::: + +## 综述 + +Asset tracking allows you to determine exactly which hardware is installed on a vehicle, providing serial number, version, and other information. +This makes it easier to track and maintain specific vehicle parts across multiple vehicles, to quickly see what versions you're running when debugging, and log component information for regulatory audits. + +Asset tracking automatically collects and logs the following metadata from external devices: + +- **Device identification**: Vendor name, model name, device type +- **Version information**: Firmware version, hardware version +- **Unique identifiers**: Serial number, device ID +- **Device capabilities**: ESC, GPS, magnetometer, barometer, etc. + +This information is published via the [`device_information`](../msg_docs/DeviceInformation.md) uORB topic and logged to flight logs. +This enables fleet management, maintenance tracking, and troubleshooting. + +## Viewing Device Information + +### Real-Time Monitoring + +You can view device information in real-time using the [MAVLink Shell](../debug/mavlink_shell.md) or console: + +```sh +listener device_information +``` + +Example output for a CAN GPS module: + +```plain +TOPIC: device_information + device_information + timestamp: 16258961403 (0.216525 seconds ago) + device_id: 8944643 (Type: 0x88, UAVCAN:0 (0x7C)) + device_type: 5 + vendor_name: "cubepilot" + model_name: "here4" + firmware_version: "1.14.3006590" + hardware_version: "4.19" + serial_number: "1c00410018513331" +``` + +Device information is published in a round-robin fashion for each detected device, at a rate of approximately 1 Hz. + +### Multi-Capability Devices + +Devices with multiple sensors (e.g., a CAN GPS/magnetometer combo module like the HERE4) register separate device information entries for each capability. +Each entry shares the same serial number and base metadata but has a different `device_id` corresponding to the specific sensor capability. + +## 飞行日志分析 + +Device information is automatically logged to flight logs. +You can extract it using [pyulog](../log/flight_log_analysis.md#pyulog), though note that fields like vendor name, model name, and serial number are stored as `char` arrays and require additional parsing. + +## 另见 + +- [CAN (DroneCAN & Cyphal)](../can/index.md) — CAN bus configuration and setup +- [DroneCAN](../dronecan/index.md) — DroneCAN-specific documentation +- [Flight Log Analysis](../log/flight_log_analysis.md) — Flight log analysis diff --git a/docs/zh/dronecan/ark_g5_rtk_gps.md b/docs/zh/dronecan/ark_g5_rtk_gps.md new file mode 100644 index 0000000000..67c3145a0f --- /dev/null +++ b/docs/zh/dronecan/ark_g5_rtk_gps.md @@ -0,0 +1,112 @@ +# ARK G5 RTK GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band [RTK GPS](../gps_compass/rtk_gps.md). + +The module incorporates the [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 传感器 + - [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 蜂鸣器 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 尺寸 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 硬件安装 + +### 布线 + +The ARK G5 RTK GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 Configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)). + +步骤如下: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 配置 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK GPS from the vehicle's centre of gravity. + +## LED含义 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## 另见 + +- [ARK G5 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_g5_rtk_heading_gps.md b/docs/zh/dronecan/ark_g5_rtk_heading_gps.md new file mode 100644 index 0000000000..c8ffb4367e --- /dev/null +++ b/docs/zh/dronecan/ark_g5_rtk_heading_gps.md @@ -0,0 +1,150 @@ +# ARK G5 RTK HEADING GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK HEADING GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band dual antenna [RTK GPS](../gps_compass/rtk_gps.md) that additionally provides vehicle yaw information from GPS. + +The module incorporates the [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK HEADING GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-heading-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 传感器 + - [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 蜂鸣器 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 尺寸 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 硬件安装 + +### 布线 + +The ARK G5 RTK HEADING GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK HEADING GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)). + +步骤如下: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK HEADING GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 配置 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK HEADING GPS from the vehicle's centre of gravity. + +### Parameter references + +This GPS is using ARK's private driver, the prameters below only exist on the firmware we ship the GPS with. You can set these params either in QGC or using the DroneCAN GUI Tool. + +#### SEP_OFFS_YAW (float) + +Heading offset angle for dual antenna GPS setups that support heading estimation. +Set this to 0 if the antennas are parallel to the forward-facing direction of the vehicle and the Rover/ANT2 antenna is in front. +The offset angle increases clockwise. +Set this to 90 if the ANT2 antenna is placed on the right side of the vehicle and the Moving Base/MAIN antenna is on the left side. + +- Default: 0 +- Min: -360 +- Max: 360 +- Unit: degree + +#### SEP_OFFS_PITCH (float) + +Vertical offsets can be compensated for by adjusting the Pitch offset. +Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. + +- Default: 0 +- Min: -90 +- Max: 90 +- Unit: degree + +#### SEP_OUT_RATE (enum) + +Configures the output rate for GNSS data messages. + +- -1: OnChange (Default) +- 50: 50 ms +- 100: 100 ms +- 200: 200 ms +- 500: 500 ms + +## LED含义 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## 另见 + +- [ARK G5 RTK HEADING GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/index.md b/docs/zh/dronecan/index.md index 9f9da4358b..24cccd66d5 100644 --- a/docs/zh/dronecan/index.md +++ b/docs/zh/dronecan/index.md @@ -27,6 +27,8 @@ Connecting peripherals over DroneCAN has many benefits: - Wiring is less complicated as you can have a single bus for connecting all your ESCs and other DroneCAN peripherals. - Setup is easier as you configure ESC numbering by manually spinning each motor. - It allows users to configure and update the firmware of all CAN-connected devices centrally through PX4. +- PX4 automatically tracks device information (vendor, model, versions, serial numbers) for maintenance and fleet management. + See [Asset Tracking](../debug/asset_tracking.md). ## 支持的硬件 diff --git a/docs/zh/features_fw/gain_compression.md b/docs/zh/features_fw/gain_compression.md index 6bcd0ef3e0..eaee06ce5e 100644 --- a/docs/zh/features_fw/gain_compression.md +++ b/docs/zh/features_fw/gain_compression.md @@ -1,6 +1,6 @@ # Gain compression - + Automatic gain compression reduces the gains of the angular-rate PID whenever oscillations are detected. It monitors the angular-rate controller output through a band-pass filter to identify these oscillations. diff --git a/docs/zh/flight_controller/micoair743-lite.md b/docs/zh/flight_controller/micoair743-lite.md index b3a76a0065..43eea95fdb 100644 --- a/docs/zh/flight_controller/micoair743-lite.md +++ b/docs/zh/flight_controller/micoair743-lite.md @@ -1,6 +1,6 @@ # MicoAir743-Lite - + :::warning PX4 does not manufacture this (or any) autopilot. diff --git a/docs/zh/flight_controller/radiolink_pix6.md b/docs/zh/flight_controller/radiolink_pix6.md index 085303d461..73c70f12cf 100644 --- a/docs/zh/flight_controller/radiolink_pix6.md +++ b/docs/zh/flight_controller/radiolink_pix6.md @@ -1,6 +1,6 @@ # RadiolinkPIX6 Flight Controller - + :::warning PX4 does not manufacture this (or any) autopilot. diff --git a/docs/zh/flight_controller/x-mav_ap-h743r1.md b/docs/zh/flight_controller/x-mav_ap-h743r1.md index c60956e904..9370f785d3 100644 --- a/docs/zh/flight_controller/x-mav_ap-h743r1.md +++ b/docs/zh/flight_controller/x-mav_ap-h743r1.md @@ -1,6 +1,6 @@ -# AP-H743-R1 +# AP-H743-R1 Flight Controller - + :::warning PX4 does not manufacture this (or any) autopilot. diff --git a/docs/zh/flight_modes_fw/hold.md b/docs/zh/flight_modes_fw/hold.md index c626e198d9..f47d5873e8 100644 --- a/docs/zh/flight_modes_fw/hold.md +++ b/docs/zh/flight_modes_fw/hold.md @@ -2,11 +2,14 @@ -The _Hold_ flight mode causes the vehicle to loiter (circle) around its current GPS position and maintain its current altitude. +The _Hold_ flight mode causes the vehicle to loiter around its current GPS position and maintain its current altitude. + +The mode supports a [number of distinct loiter modes](#loiter-modes), which are triggered using different QGC controls or MAVLink commands. +These allow loitering with circular and figure 8 flight paths. :::tip _Hold mode_ can be used to pause a mission or to help you regain control of a vehicle in an emergency. -It is usually activated with a pre-programmed switch. +It is usually activated with a pre-programmed RC switch. ::: ::: info @@ -24,24 +27,80 @@ It is usually activated with a pre-programmed switch. ::: -## 技术总结 +## Loiter modes -The aircraft circles around the GPS hold position at the current altitude. -The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. +### Default Loiter -RC stick movement is ignored. +The aircraft circles around the position at which the mode was triggered and maintain its current altitude. +The loiter radius is set by the parameter [NAV_LOITER_RAD](#NAV_LOITER_RAD). +Note that if the vehicle altitude is below [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT), it will ascend to that minimum altitude before circling. -### 参数 +The default loiter mode is entered when you switch to Hold mode without explicitly specifying any loiter behaviour. +For example, if you switch to Hold mode using an RC switch, select **Hold** on the QGC flight mode selector, or activate the mode using the MAVLink [MAV_CMD_DO_SET_MODE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) command. + +### Orbit Loiter Mode + + + +The aircraft travels towards a _specified_ orbit center position, then circles it with a given direction and radius. + +This behaviour can be accessed in QGroundControl by clicking on the map in Fly view, selecting **Orbit at Location**, and configuring the radius. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) command. +Note that PX4 respects the specified centre point (`param5`, `param6`, `param7`), and the radius and direction (`param1`). +PX4 ignores `param3` (Yaw behaviour) and `param4` (Orbits). +The value of `param2` (velocity) is also ignored, but the speed can be controlled using the [MAV_CMD_DO_CHANGE_SPEED](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) command (constrained between `FW_AIRSPD_MAX` and `FW_AIRSPD_MIN`). +PX4 outputs orbit status using the [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) message. + +### Figure 8 Loiter Mode + + + +The aircraft flys towards the closest point on a specified figure 8 path and then follows it. +The path is defined by the figure 8 centre position, orientation, and radius of two circles. + +The feature is experimental, and is not present in PX4 firmware by default (on most flight controller boards). +It can be included by setting the `CONFIG_FIGURE_OF_EIGHT` key in the [PX4 board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) for your board and rebuilding. +For example, this is enabled on the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/auterion/fmu-v6s/default.px4board#L46) file for the `auterion/fmu-v6s` board. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) command (PX4 respects all the parameters). +PX4 outputs the figure 8 status using the [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) message. + +:::info +Figure 8 loitering is not currently supported by QGC: [QGC#12778: Need Support Figure of eight (8 figure) loitering by QGC](https://github.com/mavlink/qgroundcontrol/issues/12778). +::: + +Figure 8 loitering is also available in the simulator. +You can test it in [Gazebo](../sim_gazebo_gz/index.md) using a fixed wing frame: + +```sh +make px4_sitl gz_rc_cessna +``` + +## 参数 Hold mode behaviour can be configured using the parameters below. | 参数 | 描述 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | | [NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | Minimum height for loiter mode (vehicle will ascend to this altitude if mode is engaged at a lower altitude). | +## MAVLink Commands + +The following commands are relevant to this mode: + +- [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) - Switch to Hold mode and start the specified [Orbit loiter](#orbit-loiter-mode). + Params 2 (velocity), 3 (yaw), 4 (orbits) are ignored. + [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) is emitted. +- [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) - Switch to Hold mode and start the specified [Figure 8 loiter](#figure-8-loiter-mode). + All params are respected. + [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) is emitted. + +Note, other commands may be supported. + ## 另见 -[Hold Mode (MC)](../flight_modes_mc/hold.md) +- [Hold Mode (MC)](../flight_modes_mc/hold.md) diff --git a/docs/zh/flight_modes_fw/takeoff.md b/docs/zh/flight_modes_fw/takeoff.md index 4561d8c8e4..92f085c721 100644 --- a/docs/zh/flight_modes_fw/takeoff.md +++ b/docs/zh/flight_modes_fw/takeoff.md @@ -49,8 +49,8 @@ If the local position is invalid or becomes invalid while executing the takeoff, ::: info -- Takeoff towards a target position was added in . -- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . +- Takeoff towards a target position was added in . +- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . - QGroundControl does not support `MAV_CMD_NAV_TAKEOFF` (at time of writing). ::: diff --git a/docs/zh/gps_compass/rtk_gps.md b/docs/zh/gps_compass/rtk_gps.md index fab0ad4932..2b12d8208a 100644 --- a/docs/zh/gps_compass/rtk_gps.md +++ b/docs/zh/gps_compass/rtk_gps.md @@ -20,52 +20,59 @@ The RTK compatible devices below that are expected to work with PX4 (it omits di The table indicates devices that also output yaw, and that can provide yaw when two on-vehicle units are used. It also highlights devices that connect via the CAN bus, and those which support PPK (Post-Processing Kinematic). -| 设备 | GPS | 罗盘 | [DroneCAN](../dronecan/index.md) | [GPS Yaw](#configuring-gps-as-yaw-heading-source) | PPK | -| :------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------: | :-------------------------: | :------------------------------: | :-----------------------------------------------: | :-------------------------: | -| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | -| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna][SeptDualAnt] | | -| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | BMP390 | ✓ | | | -| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | -| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | -| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | -| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | -| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P](https://docs.datagnss.com/gnss/gnss_module/D10P_RTK) | IST8310 | | ✘ | | -| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | -| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | -| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | -| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | -| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | -| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna][UnicoreDualAnt] | | -| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | -| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | -| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | -| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | -| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | -| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | +| 设备 | GPS | 罗盘 | [DroneCAN] | [GPS Yaw] | PPK | +| :------------------------------------------------------------------------------------------------------------------- | :------------------: | :-------------------------: | :-------------------------: | :---------------------------------: | :-------------------------: | +| [ARK G5 RTK GPS](../dronecan/ark_g5_rtk_gps.md) | [mosaic-G5 P3] | IIS2MDC | ✓ | | | +| [ARK G5 RTK HEADING GPS](../dronecan/ark_g5_rtk_heading_gps.md) | [mosaic-G5 P3H] | IIS2MDC | ✓ | [Heading Capability][mosaic-G5 P3H] | | +| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | +| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna] | | +| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | IIS2MDC | ✓ | | | +| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | +| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P] | | +| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P] | | +| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | +| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | +| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | +| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P] | | +| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P] | IST8310 | | ✘ | | +| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | +| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | +| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | +| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P] | | +| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P] | | +| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | +| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P] | | +| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | +| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna] | | +| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | +| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | +| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P] | | +| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | +| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | +| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | +| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P] | | +| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P] | | +| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | [RaccnLabL1L2ZED-F9P ext_ant]: https://docs.raccoonlab.co/guide/gps_mag_baro/gnss_external_antenna_f9p_v320.html [RaccoonLab L1/L2 ZED-F9P]: https://docs.raccoonlab.co/guide/gps_mag_baro/gps_l1_l2_zed_f9p.html -[DualF9P]: ../gps_compass/u-blox_f9p_heading.md -[SeptDualAnt]: ../gps_compass/septentrio.md#gnss-based-heading -[UnicoreDualAnt]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw +[Dual F9P]: ../gps_compass/u-blox_f9p_heading.md +[Septentrio Dual Antenna]: ../gps_compass/septentrio.md#gnss-based-heading +[Unicore Dual Antenna]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw [DATAGNSS GEM1305 RTK]: ../gps_compass/rtk_gps_gem1305.md +[DroneCAN]: ../dronecan/index.md +[GPS Yaw]: #configuring-gps-as-yaw-heading-source +[mosaic-G5 P3]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3 +[mosaic-G5 P3H]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H +[D10P]: https://docs.datagnss.com/gnss/gnss_module/D10P_RTK 备注: @@ -145,6 +152,7 @@ The RTK GPS connection is essentially plug and play: ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) 4. 测量完成: + - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) diff --git a/docs/zh/hardware/porting_guide.md b/docs/zh/hardware/porting_guide.md index 1ef16f8b16..3a763ed73f 100644 --- a/docs/zh/hardware/porting_guide.md +++ b/docs/zh/hardware/porting_guide.md @@ -49,7 +49,7 @@ PX4 由两个主要层组成: 基于主机操作系统(NuttX、Linux 或任 ## RC UART 接线建议 -It is generally recommended to connect RC via separate RX and TX pins to the microcontroller. If however RX and TX are connected together, the UART has to be put into singlewire mode to prevent any contention. This is done via board config and manifest files. One example is px4fmu-v5. +通常建议通过独立的RX和TX引脚将RC连接至微控制器。但若RX和TX引脚连接在一起,则必须将UART置于单线模式以避免竞争冲突。此操作需通过板级配置文件和清单文件实现。示例可参考px4fmu-v5。 如果 RX 和 TX 连在了一起,那么 UART 需要设置为单线模式以防止出现争用。 这可以用过对飞控板的配置文件和 manifest 文件进行更改来实现。 一个例子是 [px4fmu-v5](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/src/manifest.c)。 @@ -68,7 +68,7 @@ PX4项目支持并维护[FMU标准参考硬件](../hardware/reference_design.md) - [飞行测试](../test_and_ci/test_flights.md) 我们鼓励电路板制造商致力于实现与[FMU规范](https://pixhawk.org/)的完全兼容。 -We encourage board manufacturers to aim for full compatibility with the FMU spec. With full compatibility you benefit from the ongoing day-to-day development of PX4, but have none of the maintenance costs that come from supporting deviations from the specification. +我们鼓励电路板制造商致力于实现与FMU规范的完全兼容。通过完全兼容,您既能受益于PX4持续的日常开发成果,又无需承担因支持偏离规范而产生的维护成本。 :::tip 制造商在偏离规格时应仔细考虑维护成本(制造商的成本与偏离程度成正比)。 @@ -76,7 +76,7 @@ We encourage board manufacturers to aim for full compatibility with the [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX): Index-based namespace definition + - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. :::info Many ports are already have a default configuration. @@ -439,7 +441,7 @@ PX4_UXRCE_DDS_NS=uav_1 make px4_sitl gz_x500 ::: -- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. diff --git a/docs/zh/neural_networks/index.md b/docs/zh/neural_networks/index.md new file mode 100644 index 0000000000..af62fb983d --- /dev/null +++ b/docs/zh/neural_networks/index.md @@ -0,0 +1,21 @@ +# Neural Network Control + +PX4 supports the following mechanisms for using neural networks for multirotor control: + +- [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) — A generic neural network module that you can modify to use different underlying neural network and training models and compile into the firmware. +- [RAPTOR: A Neural Network Module for Adaptive Quadrotor Control](../neural_networks/raptor.md) — An adaptive RL NN module that works well with different Quad configurations without additional training. + +Generally you will select the former if you wish to experiment with custom neural network architectures and train them using PyTorch or TensorFlow, and the latter if you want to use a pre-trained neural-network controller that works out-of-the-box (without training for your particular platform) or if you train your own policies using [RLtools](https://rl.tools). + +Note that both modules are experimental and provided for experimentation. +The table below provides more detail on the differences. + +| Use Case | [`mc_raptor`](../neural_networks/raptor.md) | [`mc_nn_control`](../neural_networks/mc_neural_network_control.md) | +| ---------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ | +| Pre-trained policy that adapts to any quadrotor without training | ✓ RAPTOR | ✘ | +| Train policy in PyTorch/TF | ✘ | ✓ TF Lite | +| Train policy in RLtools | ✓ | ✘ | +| Use manual control (remote) with NN policy | ✘ GPS/MoCap | ✓ Manual attitude commands | +| Load policy checkpoints from SD card | ✓ Upload via MAVLink FTP | ✘ Compiled into firmware | +| Offboard setpoints | ✓ MAVLink | ✘ | +| Internal Trajectory Generator | ✓ (Position, Lissajous) | ✘ | diff --git a/docs/zh/neural_networks/mc_neural_network_control.md b/docs/zh/neural_networks/mc_neural_network_control.md new file mode 100644 index 0000000000..5e06f6a4c5 --- /dev/null +++ b/docs/zh/neural_networks/mc_neural_network_control.md @@ -0,0 +1,119 @@ +# MC Neural Networks Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. +It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. + +The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](./tflm.md) module. +The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. +While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. +Note that after training the network you will need to update and rebuild PX4. + +TLFM is a mature inference library intended for use on embedded devices. +It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. +If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). + +This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. +The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. + +If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). + +## Neural Network PX4 Firmware + +:::warning +This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). +::: + +The module has been tested on a number of configurations, which can be build locally using the commands: + +```sh +make px4_sitl_neural +``` + +```sh +make px4_fmu-v6c_neural +``` + +```sh +make mro_pixracerpro_neural +``` + +You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: + +```sh +CONFIG_LIB_TFLM=y +CONFIG_MODULES_MC_NN_CONTROL=y +``` + +:::tip +The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. +::: + +## Example Module Overview + +The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: + +![neural_control](../../assets/advanced/neural_control.png) + +In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. +We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. +We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) + +### Input + +The input can be changed to whatever you want. +Set up the input you want to use during training and then provide the same input in PX4. +In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: + +- [3] Local position error. (goal position - current position) +- [6] The first 2 rows of a 3 dimensional rotation matrix. +- [3] Linear velocity +- [3] Angular velocity + +All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. +PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. +Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. + +![ENU-NED](../../assets/advanced/ENU-NED.png) + +ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. + +### 输出 + +The output consists of 4 values, the motor forces, one for each motor. +These are transformed in the `RescaleActions()` function. +This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. +So the output from the network needs to be normalized before they can be sent to the motors in PX4. + +The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. +The publishing is handled in `PublishOutput(float* command_actions)` function. + +:::tip +If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. +Decrease it for more thrust. +::: + +## Training your own Network + +The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). +But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. + +Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. +If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). + +You should do one system identification flight for this and get an approximate inertia matrix for your platform. +On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). + +Then do the following steps: + +- Do a hover flight +- Read of the logs what RPM is required for the drone to hover. +- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. +- Insert these values into the Aerial Gym configuration and train your network. +- Convert the network as explained in [TFLM](tflm.md). diff --git a/docs/zh/neural_networks/nn_module_utilities.md b/docs/zh/neural_networks/nn_module_utilities.md new file mode 100644 index 0000000000..7c9054ed17 --- /dev/null +++ b/docs/zh/neural_networks/nn_module_utilities.md @@ -0,0 +1,86 @@ +# Neural Network Module: System Integration + +The neural control module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) implements an end-to-end controller utilizing neural networks. + +The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](./tflm.md). +This page covers the changes that were made to integrate the module into PX4, both within the module, and in larger system configuration. + +:::tip +This topic should help you to shape the module to your own needs. + +You will need some familiarity with PX4 development. +For more information see the developer [Getting Started](../dev_setup/getting_started.md). +::: + +## Autostart + +A line to autostart the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module has been added in the [`ROMFS/px4fmu_common/init.d/rc.mc_apps`](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rc.mc_apps) startup script. + +It checks whether the module is included by looking for the parameter [MC_NN_EN](../advanced_config/parameter_reference.md#MC_NN_EN). +If this is set to `1` (the default value), the module will be started when booting PX4. +Similarly you could create other parameters in the [`mc_nn_control_params.c`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/mc_nn_control_params.c) file for other startup script checks. + +## Custom Flight Mode + +The module creates its own flight mode "Neural Control" which lets you choose it from the flight mode menu in QGC and bind it to a switch on you RC controller. +This is done by using the [ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) internally. +This involves several steps and is visualized here: + +:::info +The module does not actually use ROS 2, it just uses the API exposed through uORB topics. +::: + +:::info +In some QGC versions the flight mode does not show up, so make sure to update to the newest version. +This only works for some flight controllers, so you might have to use an RC controller to switch to the correct external flight mode. +::: + +![neural_mode_registration](../../assets/advanced/neural_mode_registration.png) + +1. Publish a [RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md). + This specifies what you want to create, you can read more about this in the [Control Interface](../ros2/px4_ros2_control_interface.md). + In this case we register an arming check and a mode. +2. Wait for a [RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md). + This will give feedback on wether the mode registration was successful, and what the mode and arming check id is for the new mode. +3. [Optional] With the mode id, publish a [VehicleControlMode](../msg_docs/VehicleControlMode.md) message on the `config_control_setpoints` topic. + Here you can configure what other modules run in parallel. + The example controller replaces everything, so it turns off allocation. + If you want to replace other parts you can enable or disable the modules accordingly. +4. [Optional] With the mode id, publish a [ConfigOverrides](../msg_docs/ConfigOverrides.md) on the `config_overrides_request` topic. + (This is not done in the example module) This will let you defer failsafes or stop it from automatically disarming. +5. When the mode has been registered a [ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) will be sent, asking if your mode has everything it needs to run. + This message must be answered with a [ArmingCheckReply](../msg_docs/ArmingCheckReply.md) so the mode is not flagged as unresponsive. + In this response it is possible to set what requirements the mode needs to run, like local position. + If any of these requirements are set the commander will stop you from switching to the mode if they are not fulfilled. + It is also important to set health_component_index and num_events to 0 to not get a segmentation fault. + Unless you have a health component or events. +6. Listen to the [VehicleStatus](../msg_docs/VehicleStatus.md) topic. + If the nav_state equals the assigned `mode_id`, then the Neural Controller is activated. +7. When active the module will run the controller and publish to [ActuatorMotors](../msg_docs/ActuatorMotors.md). + If you want to replace a different part of the controller, you should find the appropriate topic to publish to. + +To see how the requests are handled you can check out [src/modules/commander/ModeManagement.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeManagement.cpp). + +## 日志 + +To add module-specific logging a new topic has been added to [uORB](../middleware/uorb.md) called [NeuralControl](../msg_docs/NeuralControl.md). +The message definition is also added in `msg/CMakeLists.txt`, and to [`src/modules/logger/logged_topics.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/logger/logged_topics.cpp) under the debug category. +For these messages to be saved in your logs you need to include `debug` in the [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) parameter. + +## Timing + +The module has two includes for measuring the inference times. +The first one is a driver that works on the actual flight controller units, but a second one, `chrono`, is loaded for SITL testing. +Which timing library is included and used is based on wether PX4 is built with NUTTX or not. + +## Changing the setpoint + +The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message's position fields to define its target. +To follow a trajectory, you can send updated setpoints. +For an example of how to do this in a PX4 module, see the [mc_nn_testing](https://github.com/SindreMHegre/PX4-Autopilot-public/tree/main/src/modules/mc_nn_testing) module in this fork. +Note that this is not included in upstream PX4. +To use it, copy the module folder from the linked repository into your workspace, and enable it by adding the following line to your `.px4board` file: + +```sh +CONFIG_MODULES_MC_NN_TESTING=y +``` diff --git a/docs/zh/neural_networks/raptor.md b/docs/zh/neural_networks/raptor.md new file mode 100644 index 0000000000..a2c94576a6 --- /dev/null +++ b/docs/zh/neural_networks/raptor.md @@ -0,0 +1,221 @@ +# RAPTOR: A Neural Network Module for Adaptive Quadrotor Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +RAPTOR is a tiny reinforcement-learning based neural network module for quadrotor control that can be used to control a wide variety of quadrotors without retuning. + +This topic provides an overview of the fundamental concepts, and explains how you can use the module in simulation and real hardware. + +## 综述 + +![Visual Abstract](../../assets/advanced/neural_networks/raptor/visual_abstract.jpg) + +RAPTOR is an adaptive policy for end-to-end quadrotor control. +It is motivated by the human ability to adapt learned behaviours to similar situations. +For example, while humans may initially require many hours of driving experience to be able to smoothly control the car and blend into traffic, when faced with a new vehicle they do not need to re-learn how to drive — they only need to experience a few rough braking/acceleration/steering responses to adjust their previously learned behavior. + +Reinforcement Learning (RL) is a machine learning technique that uses trial and error to learn decision making/control behaviors, which is similar to the way that humans learn to drive. +RL is interesting for controlling robots (and particularly UAVs) because it overcomes some fundamental limitations of classic, modular control architectures (information loss at module boundaries, requirement for expert tuning, etc). +RL has been very successful in [high-performance quadrotor flight](https://doi.org/10.1038/s41586-023-06419-4), but previous designs have not been particularly adaptable to new frames and vehicle types. + +RAPTOR fills this gap and demonstrates a single, tiny neural-network control policy that can control a wide variety of quadrotors (tested on real quadrotors from 32 g to 2.4 kg). + +For more details please refer to this video: + + + +The method we developed for training the RAPTOR policy is called Meta-Imitation Learning: + +![Diagram showing the Method Overview](../../assets/advanced/neural_networks/raptor/method.jpg) + +You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: + + + +For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). + +## Structure + +The RAPTOR control policy is an end-to-end policy that takes position, orientation, linear velocity and angular velocity as inputs and outputs motor commands (`actuator_motors`). +To integrate it into PX4 we use the external mode registration facilities in PX4 (which also works well for internal modes as demonstrated in `mc_nn_control`). +Because of this architecture the `mc_raptor` module is completely decoupled from all other PX4 logic. + +By default, the RAPTOR module expects setpoints via `trajectory_setpoint` messages. +If no `trajectory_setpoint` messages are received or if no `trajectory_setpoint` is received within 200 ms, the current position and orientation (with zero velocity) is used as the setpoint. +Since feeding setpoints reliably via telemetry is still a challenge, we also implement a simple option to generate internal reference trajectories (controlled through the `MC_RAPTOR_INTREF` parameter) for demonstration and benchmarking purposes. + +## 特性 + +- Tiny neural network (just 2084 parameters) => minimal CPU usage +- Easily maintainable + - Simple CMake setup + - Self-contained (no interference with other modules) + - Single, simple and well-maintained dependency (RLtools) +- Loading neural network parameters from SD card + - Minimal flash usage (for possible inclusion into default build configurations) + - Easy development: Train new neural network and just upload it via MAVLink FTP without requiring to re-flash the firmware +- Tested on 10+ different real platforms (including flexible frames, brushed motors) +- Actively developed and maintained + +## 用法 + +### SITL + +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate + +```sh +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 # Enable the mc_raptor module +param save +``` + +Upload the RAPTOR checkpoint to the "SD card": Separate terminal + +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` + +Restart (Ctrl+C) + +```sh +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```sh +commander mode ext{RAPTOR_MODE_ID} +``` + +#### Internal Reference Trajectory Generation + +In our experience, feeding the `trajectory_setpoint` via MAVLink (even via WiFi telemetry) is unreliable. +But we do not want to constrain this module to only platforms that have a companion board. + +For this reason we have integrated a simple internal reference trajectory generator for testing and benchmarking purposes. +It supports position (constant position and yaw setpoint) as well as configurable [Lissajous trajectories](https://en.wikipedia.org/wiki/Lissajous_curve). + +The Lissajous generator can, for example, generate smooth figure-eight trajectories that contain interesting accelerations for benchmarking and testing purposes. +Please refer to the embedded configurator later in this section to explore the Lissajous parameters and view the resulting trajectories. + +To use the internal reference generator, select the mode: `0`: Off/activation position tracking, `1`: Lissajous + +```sh +param set MC_RAPTOR_INTREF 1 +``` + +Restart (ctrl+c) + +```sh +commander takeoff +commander mode ext{RAPTOR_MODE_ID} +mc_raptor intref lissajous 0.5 1 0 2 1 1 10 3 +``` + +The trajectory is relative to the position and yaw of the vehicle at the point where the RAPTOR mode is activated (or the position and yaw where the parameters are changed if it is already activated). + +You can adjust the parameters of the trajectory with the following tool. +Make sure to copy the generated CLI string at the end: + + + +### Real-World + +#### 设置 + +The `mc_raptor` module has been mostly tested with the Holybro X500 V2 but it should also work out-of-the-box with other platforms (see the [Other Platforms](#other-platforms) section). + +```sh +make px4_fmu-v6c_raptor upload +``` + +We recommend initially testing the RAPTOR mode using a dead man's switch. +For this we configure the mode selection to be connected to a push button or a switch with a spring that automatically switches back. +In the default position we configure e.g. `Stabilized Mode` and in the pressed configuration we select `External Mode 1` (since the name of the external mode is only transmitted at runtime). +This allows to take off manually and then just trigger the RAPTOR mode for a split-second to see how it behaves. +In our experiments it has been exceptionally stable (zero crashes) but we still think progressively activating it for longer is the safest way to build confidence. + +:::warning +Make sure that your platform uses the standard PX4 quadrotor motor layout: + +1: front-right, 2: back-left, 3: front-left, 4: back-right +::: + +##### Other Platforms + +To enable the `mc_raptor` module in other platforms, just add `CONFIG_MODULES_MC_RAPTOR=y` and `CONFIG_LIB_RL_TOOLS=y` + +```diff ++++ b/boards/px4/fmu-v6c/raptor.px4board +@@ -35,2 +35,3 @@ + CONFIG_DRIVERS_UAVCAN=y ++CONFIG_LIB_RL_TOOLS=y + CONFIG_MODULES_AIRSPEED_SELECTOR=y +@@ -64,2 +65,3 @@ + CONFIG_MODULES_MC_POS_CONTROL=y ++CONFIG_MODULES_MC_RAPTOR=y + CONFIG_MODULES_MC_RATE_CONTROL=y +``` + +#### Results + +Even though there were moderate winds (~ 5 m/s) during the test, we found good figure-eight tracking performance at velocities up to 12 m/s: + +![Lissajous](../../assets/advanced/neural_networks/raptor/results_figure_eight.svg) + +We also tested the linear velocity in a straight line and found that the RAPTOR policy can reliably fly at > 17 m/s (the wind direction was orthogonal to the line): + +![Linear Oscillation](../../assets/advanced/neural_networks/raptor/results_line.svg) + +### 故障处理 + +#### 日志 + +Use this logging configuration to log all relevant topics at maximum rate: + +```sh +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` + +Use mavproxy FTP to upload it: + +```sh +mavproxy.py +``` + +##### Real + +```sh +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +##### SITL + +```sh +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/docs/zh/neural_networks/tflm.md b/docs/zh/neural_networks/tflm.md new file mode 100644 index 0000000000..ce37aae59b --- /dev/null +++ b/docs/zh/neural_networks/tflm.md @@ -0,0 +1,77 @@ +# TensorFlow Lite Micro (TFLM) + +The PX4 [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. + +This is a mature inference library intended for use on embedded devices, and is hence a suitable choice for PX4. + +This guide explains how the TFLM library is integrated into the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module, and the changes you would have to make to use it for your own neural network. + +:::tip +For more information, see the [TFLM guide](https://ai.google.dev/edge/litert/microcontrollers/get_started). +::: + +## TLMF NN Formats + +TFLM uses networks in its own [tflite format](https://ai.google.dev/edge/litert/models/convert). +However, since many microcontrollers do not have native filesystem support, a tflite file can be converted to a C++ source and header file. + +This is what is done in `mc_nn_control`. +The tflight neural network is represented in code by the files [`control_net.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.cpp) and [`control_net.hpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.hpp). + +### Getting a Network in tflite Format + +There are many online resource for generating networks in the `.tflite` format. + +For this example we trained the network in the open source [Aerial Gym Simulator](https://ntnu-arl.github.io/aerial_gym_simulator/). +Aerial Gym includes a guide, and supports RL both for control and vision-based navigation tasks. + +The project includes conversion code for `PyTorch -> TFLM` in the [resources/conversion](https://github.com/ntnu-arl/aerial_gym_simulator/tree/main/resources/conversion) folder. + +### Updating `mc_nn_control` with your own NN + +You can convert a `.tflite` network into a `.cc` file in the ubuntu terminal with this command: + +```sh +xxd -i converted_model.tflite > model_data.cc +``` + +You will then have to modify the `control_net.hpp` and `control_net.cpp` to include the data from `model_data.cc`: + +- Take the size of the network in the bottom of the `.cc` file and replace the size in `control_net.hpp`. +- Take the data in the model array in the `cc` file, and replace the ones in `control_net.cpp`. + +You are now ready to run your own network. + +## Code Explanation + +This section explains the code used to integrate the NN in `control_net.cpp`. + +### Operations and Resolver + +Firstly we need to create the resolver and load the needed operators to run inference on the NN. +This is done in the top of `mc_nn_control.cpp`. +The number in `MicroMutableOpResolver<3>` represents how many operations you need to run the inference. + +A full list of the operators can be found in the [micro_mutable_op_resolver.h](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/micro_mutable_op_resolver.h) file. +There are quite a few supported operators, but you will not find the most advanced ones. +In the control example the network is fully connected so we use `AddFullyConnected()`. +Then the activation function is ReLU, and we `AddAdd()` for the bias on each neuron. + +### Interpreter + +In the `InitializeNetwork()` we start by setting up the model that we loaded from the source and header file. +Next is to set up the interpreter, this code is taken from the TFLM documentation and is thoroughly explained there. +The end state is that the `_control_interpreter` is set up to later run inference with the `Invoke()` member function. +The `_input_tensor` is also defined, it is fetched from `_control_interpreter->input(0)`. + +### 输入 + +The `_input_tensor` is filled in the `PopulateInputTensor()` function. +`_input_tensor` works by accessing the `->data.f` member array and fill in the required inputs for your network. +The inputs used in the control network is covered in [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md). + +### Outputs + +For the outputs the approach is fairly similar to the inputs. +After setting the correct inputs, calling the `Invoke()` function the outputs can be found by getting `_control_interpreter->output(0)`. +And from the output tensor you get the `->data.f` array. diff --git a/docs/zh/releases/1.16.md b/docs/zh/releases/1.16.md index fee1f6288f..66b64f9f5b 100644 --- a/docs/zh/releases/1.16.md +++ b/docs/zh/releases/1.16.md @@ -151,6 +151,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### uXRCE-DDS / ROS2 - [PX4-Autopilot#24113](https://github.com/PX4/PX4-Autopilot/pull/24113): [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to translate PX4 messages from one definition version to another dynamically +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [ROS-based waypoint missions](../ros2/px4_ros2_waypoint_missions.md). - dds_topics: add vtol_vehicle_status ([PX4-Autopilot#24582](https://github.com/PX4/PX4-Autopilot/pull/24582)) - dds_topics: add home_position ([PX4-Autopilot#24583](https://github.com/PX4/PX4-Autopilot/pull/24583)) diff --git a/docs/zh/releases/1.17.md b/docs/zh/releases/1.17.md new file mode 100644 index 0000000000..1d32628731 --- /dev/null +++ b/docs/zh/releases/1.17.md @@ -0,0 +1,134 @@ +# PX4-Autopilot v1.17.0 Release Notes + + + + + + + +This contains changes to PX4 planned for PX4 v1.17 (since the last major release [PX v1.16](../releases/1.16.md)). + +:::warning +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in PX4 v1.17 release. +New features that are not expected to go into the v1.17 release are in [PX4-Autopilot `main` Release Notes](../releases/main.md). +::: + +## Read Before Upgrading + +TBD … + +Please continue reading for [upgrade instructions](#upgrade-guide). + +## Major Changes + +- TBD + +## Upgrade Guide + +## Other changes + +### Hardware Support + +- **[New Hardware]** boards: [MicoAir743-Lite FC](../flight_controller/micoair743-lite.md) +- **[New Hardware]** boards: [RadiolinkPIX6 FC](../flight_controller/radiolink_pix6.md) +- **[New Hardware]** boards: [AP-H743-R1 FC](../flight_controller/x-mav_ap-h743r1.md) + + + +### Control + + + +- [MC Neural Network Module](../advanced/neural_networkss.md) + +### Estimation + +- TBD + + + +### 仿真 + +- Overhaul rover simulation: + - Add synthetic differential rover model: [PX4-gazebo-models#107](https://github.com/PX4/PX4-gazebo-models/pull/107) + - Add synthetic mecanum rover model: [PX4-gazebo-models#113](https://github.com/PX4/PX4-gazebo-models/pull/113) + - Update synthetic ackermann rover model: [PX4-gazebo-models#117](https://github.com/PX4/PX4-gazebo-models/pull/117) + +- [Simulation-in-Hardware (SIH)](../sim_sih/index.md#compatibility) + - New simulation: MC Hexacopter X + - New simulation: Ackermann Rover + +### Debug & Logging + +- TBD + +### Ethernet + +- TBD + +### uXRCE-DDS / Zenoh / ROS2 + +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [Fixed Wing lateral/longitudinal setpoint](../ros2/px4_ros2_control_interface.md#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype) (`FwLateralLongitudinalSetpointType`) and [VTOL transitions](../ros2/px4_ros2_control_interface.md#controlling-a-vtol). ([PX4-Autopilot#24056](https://github.com/PX4/PX4-Autopilot/pull/24056)). +- [UXRCE_DDS: Simple index based namespace (UXRCE_DDS_NS_IDX)](../middleware/uxrce_dds.md#customizing-the-namespace) +- [Zenoh (PX4 ROS 2 rmw_zenoh)](../middleware/zenoh.md) + +### MAVLink + +- TBD + + + +### 垂直起降 + +- TBD + +### Fixed-wing + +- [Fixed Wing Takeoff mode](../flight_modes_fw/takeoff.md) will now keep climbing with level wings on position loss. + A target takeoff waypoint can be set to control takeoff course and loiter altitude. ([PX4-Autopilot#25083](https://github.com/PX4/PX4-Autopilot/pull/25083)). +- Automatically suppress angular rate oscillations using [Gain compression](../features_fw/gain_compression.md). ([PX4-Autopilot#25840: FW rate control: add gain compression algorithm](https://github.com/PX4/PX4-Autopilot/pull/25840)) + +### 无人车 + +- Removed deprecated rover module ([PX4-Autopilot#25054](https://github.com/PX4/PX4-Autopilot/pull/25054)). +- Add support for [Apps & API](../flight_modes_rover/api.md) including [Rover Setpoints](../ros2/px4_ros2_control_interface.md#rover-setpoints) ([PX4-Autopilot#25074](https://github.com/PX4/PX4-Autopilot/pull/25074), [PX4-ROS2-Interface-Lib#140](https://github.com/Auterion/px4-ros2-interface-lib/pull/140)). +- Update [rover simulation](../frames_rover/index.md#simulation) ([PX4-Autopilot#25644](https://github.com/PX4/PX4-Autopilot/pull/25644)) (see [Simulation](#simulation) release note for details). + +### ROS 2 + +- TBD diff --git a/docs/zh/releases/index.md b/docs/zh/releases/index.md index e8c4dcc49e..1e07e34cde 100644 --- a/docs/zh/releases/index.md +++ b/docs/zh/releases/index.md @@ -2,7 +2,8 @@ 这是一份 PX4 发行说明列表,其中包含每次发布所做更改的清单,详细说明了新增功能、漏洞修复、弃用内容以及更新情况。 -- [main](../releases/main.md) (changes since v1.16) +- [main](../releases/main.md) (changes planned for v1.18 or later) +- [v1.17](../releases/1.17.md) (changes planned for v1.17, since v1.16) - [v1.16](../releases/1.16.md) - [v1.15](../releases/1.15.md) - [v1.14](../releases/1.14.md) diff --git a/docs/zh/releases/main.md b/docs/zh/releases/main.md index 6d3ce5f517..b8a4d4a467 100644 --- a/docs/zh/releases/main.md +++ b/docs/zh/releases/main.md @@ -16,13 +16,13 @@ const { site } = useData(); This contains changes to PX4 `main` branch since the last major release ([PX v1.16](../releases/1.16.md)). :::warning -PX4 v1.16 is in candidate-release testing, pending release. -Update these notes with features that are going to be in `main` but not the PX4 v1.16 release. +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in `main` (PX4 v1.18 or later) but not the PX4 v1.17 release. ::: ## Read Before Upgrading -TBD … +- TBD … Please continue reading for [upgrade instructions](#upgrade-guide). @@ -45,8 +45,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Control - Added new flight mode(s): [Altitude Cruise (MC)](../flight_modes_mc/altitude_cruise.md), Altitude Cruise (FW). - For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. (PX4-Autopilot#25435: Add new flight mode: Altitude Cruise - ). + For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### Estimation @@ -59,19 +58,34 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### 仿真 +- TBD + + + +### Debug & Logging + +- [Asset Tracking](../debug/asset_tracking.md): Automatic tracking and logging of external device information including vendor name, firmware and hardware version, serial numbers. Currently supports DroneCAN devices. ([PX4-Autopilot#25617](https://github.com/PX4/PX4-Autopilot/pull/25617)) + ### Ethernet - TBD -### uXRCE-DDS / ROS2 +### uXRCE-DDS / Zenoh / ROS2 + +- TBD + + ### MAVLink @@ -92,16 +106,26 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Fixed-wing +- TBD + + ### 无人车 +- TBD + + + ### ROS 2 - TBD diff --git a/docs/zh/ros2/px4_ros2_control_interface.md b/docs/zh/ros2/px4_ros2_control_interface.md index 0095cf4d2f..625ae209b8 100644 --- a/docs/zh/ros2/px4_ros2_control_interface.md +++ b/docs/zh/ros2/px4_ros2_control_interface.md @@ -345,9 +345,9 @@ private: 以下章节提供了支持的设置点类型列表: - [MulticopterGotoSetpointType](#go-to-setpoint-multicoptergotosetpointtype): 平滑的位置控制以及(可选的)航向控制 -- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): 对横向和纵向固定翼动态的直接控制 +- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics - [DirectActuatorsSetpointType](#direct-actuator-control-setpoint-directactuatorssetpointtype):直接控制发动机和飞行地面servo setpoints -- [Rover Setpoints](#rover-setpoints): 直接访问火星车控制设定值(位置、速度、姿态、速率、油门和转向)。 +- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). :::tip 其他设置点类型目前是实验性的,可在以下网址找到:[px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental)。 @@ -414,7 +414,7 @@ _goto_setpoint->update( #### 固定翼横向与纵向设定值(FwLateralLongitudinalSetpointType,固定翼横向纵向设定值类型) - + :::info 此设定值类型支持固定翼飞行器,以及处于固定翼模式下的垂直起降飞行器(VTOL)。 @@ -556,7 +556,7 @@ _fw_lateral_longitudinal_setpoint->update(setpoint_s, config_s); #### Rover 设置点 - + 滚动模块使用层次结构来传播设置点: @@ -590,7 +590,7 @@ _fw_lateral_longitudinal_setpoint->update(setpoint_s, config_s); ### 控制VTOL - + 要在外部飞行模式下控制VTOL,需确保根据当前飞行配置返回正确的设定值类型: diff --git a/docs/zh/sim_sih/index.md b/docs/zh/sim_sih/index.md index b2b2c20c05..383c700b8c 100644 --- a/docs/zh/sim_sih/index.md +++ b/docs/zh/sim_sih/index.md @@ -27,8 +27,8 @@ The Desktop computer is only used to display the virtual vehicle. - SIH for FW (airplane) and VTOL tailsitter are supported from PX4 v1.13. - SIH as SITL (without hardware) from PX4 v1.14. - SIH for Standard VTOL from PX4 v1.16. -- SIH for MC Hexacopter X from `main` (expected to be PX4 v1.17). -- SIH for Ackermann Rover from `main`. +- SIH for MC Hexacopter X from PX4 v1.17. +- SIH for Ackermann Rover from PX4 v1.17. ### Benefits From 4af33cef4386284a70ad1e81a0cce6876d67fb5d Mon Sep 17 00:00:00 2001 From: PX4 Build Bot Date: Wed, 28 Jan 2026 16:43:23 +1100 Subject: [PATCH 03/71] New Crowdin translations - uk (#26247) Co-authored-by: Crowdin Bot --- docs/uk/SUMMARY.md | 12 +- docs/uk/advanced/gimbal_control.md | 2 +- docs/uk/advanced/neural_networks.md | 120 +--------- docs/uk/can/index.md | 4 + docs/uk/config/safety.md | 26 +-- docs/uk/debug/asset_tracking.md | 68 ++++++ docs/uk/dronecan/ark_g5_rtk_gps.md | 112 +++++++++ docs/uk/dronecan/ark_g5_rtk_heading_gps.md | 150 ++++++++++++ docs/uk/dronecan/index.md | 2 + docs/uk/features_fw/gain_compression.md | 2 +- docs/uk/flight_controller/micoair743-lite.md | 2 +- docs/uk/flight_controller/radiolink_pix6.md | 2 +- docs/uk/flight_controller/x-mav_ap-h743r1.md | 4 +- docs/uk/flight_modes_fw/hold.md | 77 +++++- docs/uk/flight_modes_fw/takeoff.md | 4 +- docs/uk/gps_compass/rtk_gps.md | 88 +++---- docs/uk/middleware/uxrce_dds.md | 6 +- docs/uk/neural_networks/index.md | 21 ++ .../mc_neural_network_control.md | 119 ++++++++++ .../uk/neural_networks/nn_module_utilities.md | 86 +++++++ docs/uk/neural_networks/raptor.md | 221 ++++++++++++++++++ docs/uk/neural_networks/tflm.md | 77 ++++++ docs/uk/releases/1.16.md | 1 + docs/uk/releases/1.17.md | 134 +++++++++++ docs/uk/releases/index.md | 3 +- docs/uk/releases/main.md | 36 ++- docs/uk/ros2/px4_ros2_control_interface.md | 10 +- docs/uk/sim_sih/index.md | 4 +- 28 files changed, 1183 insertions(+), 210 deletions(-) create mode 100644 docs/uk/debug/asset_tracking.md create mode 100644 docs/uk/dronecan/ark_g5_rtk_gps.md create mode 100644 docs/uk/dronecan/ark_g5_rtk_heading_gps.md create mode 100644 docs/uk/neural_networks/index.md create mode 100644 docs/uk/neural_networks/mc_neural_network_control.md create mode 100644 docs/uk/neural_networks/nn_module_utilities.md create mode 100644 docs/uk/neural_networks/raptor.md create mode 100644 docs/uk/neural_networks/tflm.md create mode 100644 docs/uk/releases/1.17.md diff --git a/docs/uk/SUMMARY.md b/docs/uk/SUMMARY.md index 3e1e9c1f3c..bb59e97e97 100644 --- a/docs/uk/SUMMARY.md +++ b/docs/uk/SUMMARY.md @@ -128,6 +128,7 @@ - [Значення світлодіодів](getting_started/led_meanings.md) - [Значення звуків та мелодій](getting_started/tunes.md) - [QGroundControl Flight-Readiness Status](flying/pre_flight_checks.md) + - [Asset Tracking](debug/asset_tracking.md) - [Вибір обладнання & Налаштування](hardware/drone_parts.md) - [Flight Controllers (Autopilots)](flight_controller/index.md) @@ -273,6 +274,8 @@ - [Holybro M8N & M9N GPS](gps_compass/gps_holybro_m8n_m9n.md) - [Sky-Drones SmartAP GPS](gps_compass/gps_smartap.md) - [RTK GNSS](gps_compass/rtk_gps.md) + - [ARK G5 RTK GPS](dronecan/ark_g5_rtk_gps.md) + - [ARK G5 RTK HEADING GPS](dronecan/ark_g5_rtk_heading_gps.md) - [ARK RTK GPS (CAN)](dronecan/ark_rtk_gps.md) - [ARK RTK GPS L1 L5 (CAN)](dronecan/ark_rtk_gps_l1_l2.md) - [ARK X20 RTK GPS (CAN)](dronecan/ark_x20_rtk_gps.md) @@ -840,9 +843,11 @@ - [Інтеграція камери/Архітектура](camera/camera_architecture.md) - [Комп'ютерний зір](advanced/computer_vision.md) - [Захоплення руху (VICON, Optitrack, NOKOV)](tutorials/motion-capture.md) - - [Neural Networks](advanced/neural_networks.md) - - [Neural Network Module Utilities](advanced/nn_module_utilities.md) - - [TensorFlow Lite Micro (TFLM)](advanced/tflm.md) + - [Neural Networks](neural_networks/index.md) + - [MC NN Control Module (Generic)](neural_networks/mc_neural_network_control.md) + - [Neural Network Module Utilities](neural_networks/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](neural_networks/tflm.md) + - [RAPTOR Adaptive RL NN Module](neural_networks/raptor.md) - [Встановлюється драйвер для Intel RealSense R200](advanced/realsense_intel_driver.md) - [Перемикання оцінювачів стану](advanced/switching_state_estimators.md) - [Out-of-Tree модулі](advanced/out_of_tree_modules.md) @@ -925,6 +930,7 @@ - [Релізи](releases/index.md) - [main (alpha)](releases/main.md) + - [1.17 (alpha)](releases/1.17.md) - [1.16 (stable)](releases/1.16.md) - [1.15](releases/1.15.md) - [1.14](releases/1.14.md) diff --git a/docs/uk/advanced/gimbal_control.md b/docs/uk/advanced/gimbal_control.md index 3a8bbe08ff..68ca5a651f 100644 --- a/docs/uk/advanced/gimbal_control.md +++ b/docs/uk/advanced/gimbal_control.md @@ -74,7 +74,7 @@ Gimbal також можна контролювати шляхом підклю ![Gimbal Actuator config](../../assets/config/actuators/qgc_actuators_gimbal.png) -PWM значення для використання при відблокованому, максимальному та мінімальному значеннях можна визначити так само, як і для інших сервоприводів, використовуючи [повзунки тесту приводу](../config/actuators.md#actuator-testing), щоб підтвердити, що кожний повзунок переміщує відповідну вісь, і змінюючи значення так, щоб гімбал знаходився у відповідному положенні при відблокованому стані, низькому і високому положенні повзунка. +The PWM values to use for the disarmed, maximum, center and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low, center and high position in the slider. Значення також можуть бути наведені у документації гімбала. ## Gimbal Control in Missions diff --git a/docs/uk/advanced/neural_networks.md b/docs/uk/advanced/neural_networks.md index ce106057fa..039259fd5f 100644 --- a/docs/uk/advanced/neural_networks.md +++ b/docs/uk/advanced/neural_networks.md @@ -1,119 +1 @@ -# Neural Networks - - - -:::warning -This is an experimental module. -Use at your own risk. -::: - -The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. -It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. - -The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md) module. -The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. -While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. -Note that after training the network you will need to update and rebuild PX4. - -TLFM is a mature inference library intended for use on embedded devices. -It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. -If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). - -This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. -The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. - -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). - -## Neural Network PX4 Firmware - -:::warning -This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). -::: - -The module has been tested on a number of configurations, which can be build locally using the commands: - -```sh -make px4_sitl_neural -``` - -```sh -make px4_fmu-v6c_neural -``` - -```sh -make mro_pixracerpro_neural -``` - -You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: - -```sh -CONFIG_LIB_TFLM=y -CONFIG_MODULES_MC_NN_CONTROL=y -``` - -:::tip -The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. -::: - -## Example Module Overview - -The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: - -![neural_control](../../assets/advanced/neural_control.png) - -In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. -We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. -We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) - -### Вхід - -The input can be changed to whatever you want. -Set up the input you want to use during training and then provide the same input in PX4. -In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: - -- [3] Local position error. (goal position - current position) -- [6] The first 2 rows of a 3 dimensional rotation matrix. -- [3] Linear velocity -- [3] Angular velocity - -All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. -PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. -Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. - -![ENU-NED](../../assets/advanced/ENU-NED.png) - -ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. - -### Output - -The output consists of 4 values, the motor forces, one for each motor. -These are transformed in the `RescaleActions()` function. -This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. -So the output from the network needs to be normalized before they can be sent to the motors in PX4. - -The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. -The publishing is handled in `PublishOutput(float* command_actions)` function. - -:::tip -If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. -Decrease it for more thrust. -::: - -## Training your own Network - -The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). -But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. - -Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. -If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). - -You should do one system identification flight for this and get an approximate inertia matrix for your platform. -On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). - -Then do the following steps: - -- Do a hover flight -- Read of the logs what RPM is required for the drone to hover. -- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. -- Insert these values into the Aerial Gym configuration and train your network. -- Convert the network as explained in [TFLM](tflm.md). + diff --git a/docs/uk/can/index.md b/docs/uk/can/index.md index 82c5ae4c13..14ebfa20ff 100644 --- a/docs/uk/can/index.md +++ b/docs/uk/can/index.md @@ -10,6 +10,10 @@ CAN it is designed to be democratic and uses differential signaling. For this reason it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. CAN також дозволяє отримання зворотного зв'язку від периферійних пристроїв та зручне оновлення прошивки через шину. +PX4 has the ability to track and log detailed information from CAN devices, including firmware versions, hardware versions, and serial numbers. +This enables unique identification and lifecycle tracking of hardware connected to the flight controller. +See [Asset Tracking](../debug/asset_tracking.md) for more information. + PX4 підтримує два програмні протоколи для взаємодії з пристроями CAN: - [DroneCAN](../dronecan/README.md): PX4 рекомендує це для більшості типових налаштувань. diff --git a/docs/uk/config/safety.md b/docs/uk/config/safety.md index 2ae88fb8a6..d4407a9fa4 100644 --- a/docs/uk/config/safety.md +++ b/docs/uk/config/safety.md @@ -119,36 +119,32 @@ PX4 and the receiver may also need to be configured in order to _detect RC loss_ ![Safety - RC Loss (QGC)](../../assets/qgc/setup/safety/safety_rc_loss.png) -The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [RC Loss timeout](#COM_RC_LOSS_T). -Users that want to disable the RC loss failsafe in specific automatic modes (mission, hold, offboard) can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). +The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [manual control loss timeout](#COM_RC_LOSS_T). +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). Нижче наведено додаткові (і базові) налаштування параметрів. | Параметр | Налаштування | Опис | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Аварійний режим втрати ручного керування Timeout | Час після отримання останньої встановленої точки від вибраного джерела керування вручну, після якого керування вважається втраченим. Це повинно бути коротким, оскільки транспортний засіб продовжуватиме літати за старими налаштуваннями керування вручну, поки не спрацює таймаут. | +| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Аварійний режим втрати ручного керування Timeout | Час після отримання останньої встановленої точки від вибраного джерела керування вручну, після якого керування вважається втраченим. This must be kept short because the vehicle will continue to fly using the last known stick position until the timeout triggers. | | [COM_FAIL_ACT_T](../advanced_config/parameter_reference.md#COM_FAIL_ACT_T) | Затримка відмови від дії | Delay in seconds between failsafe condition being triggered (`COM_RC_LOSS_T`) and failsafe action (RTL, Land, Hold). У цьому стані транспортний засіб очікує в режимі утримання на повторне підключення джерела керування вручну. Це може бути встановлено довше для довгих польотів, щоб втрата інтермітентного з'єднання не викликала негайного виклику аварійного режиму. Це може бути рівним нулю, щоб аварійний запобіжник спрацював негайно. | | [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | Моделювання відмовостійкості | Вимкнути, Блукати, Повернутися, Приземлитися, Роззброїти, Завершити. | -| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | Виключення втрат RC | Встановіть режими, в яких втрата керування вручну ігнорується: Місія, Утримання, Offboard. | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | Виключення втрат RC | Set modes in which manual control loss is ignored. | ## Втрата каналу зв'язку Failsafe -Збій втрати втрати даних посилання (при переході через телеметрію (підключення до наземної станції) втрачено. +The Data Link Loss failsafe is triggered if the connection to the last MAVLink ground station like QGroundControl is lost. +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_DLL_EXCEPT](#COM_DLL_EXCEPT). ![Safety - Data Link Loss (QGC)](../../assets/qgc/setup/safety/safety_data_link_loss.png) Налаштування та вибрані параметри показані нижче. -| Налаштування | Параметр | Опис | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| Тайм-аут втрати каналу зв'язку | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | Час після втрати з'єднання з даними перед тим, як спрацює запобіжник. | -| Моделювання відмовостійкості | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Вимкнути, Hold mode, Return mode, Land mode, Роззброїти, Завершити. | - -Також застосовуються наступні налаштування, але вони не відображаються в інтерфейсі QGC. - -| Налаштування | Параметр | Опис | -| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes where DL loss will not trigger a failsafe. | +| Налаштування | Параметр | Опис | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| Тайм-аут втрати каналу зв'язку | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | Час після втрати з'єднання з даними перед тим, як спрацює запобіжник. | +| Моделювання відмовостійкості | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Вимкнути, Hold mode, Return mode, Land mode, Роззброїти, Завершити. | +| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes in which data link loss is ignored. | ## Аварійний режим "обмеження зони політів" diff --git a/docs/uk/debug/asset_tracking.md b/docs/uk/debug/asset_tracking.md new file mode 100644 index 0000000000..6ed230b97c --- /dev/null +++ b/docs/uk/debug/asset_tracking.md @@ -0,0 +1,68 @@ +# Asset Tracking + + + +PX4 can track and log detailed information about external hardware devices connected to the flight controller. +This enables unique identification of vehicle parts throughout their operational lifetime using device IDs, serial numbers, and version information. + +:::info +Asset tracking is currently implemented for [DroneCAN](../dronecan/index.md) devices only. +::: + +## Загальний огляд + +Asset tracking allows you to determine exactly which hardware is installed on a vehicle, providing serial number, version, and other information. +This makes it easier to track and maintain specific vehicle parts across multiple vehicles, to quickly see what versions you're running when debugging, and log component information for regulatory audits. + +Asset tracking automatically collects and logs the following metadata from external devices: + +- **Device identification**: Vendor name, model name, device type +- **Version information**: Firmware version, hardware version +- **Unique identifiers**: Serial number, device ID +- **Device capabilities**: ESC, GPS, magnetometer, barometer, etc. + +This information is published via the [`device_information`](../msg_docs/DeviceInformation.md) uORB topic and logged to flight logs. +This enables fleet management, maintenance tracking, and troubleshooting. + +## Viewing Device Information + +### Real-Time Monitoring + +You can view device information in real-time using the [MAVLink Shell](../debug/mavlink_shell.md) or console: + +```sh +listener device_information +``` + +Example output for a CAN GPS module: + +```plain +TOPIC: device_information + device_information + timestamp: 16258961403 (0.216525 seconds ago) + device_id: 8944643 (Type: 0x88, UAVCAN:0 (0x7C)) + device_type: 5 + vendor_name: "cubepilot" + model_name: "here4" + firmware_version: "1.14.3006590" + hardware_version: "4.19" + serial_number: "1c00410018513331" +``` + +Device information is published in a round-robin fashion for each detected device, at a rate of approximately 1 Hz. + +### Multi-Capability Devices + +Devices with multiple sensors (e.g., a CAN GPS/magnetometer combo module like the HERE4) register separate device information entries for each capability. +Each entry shares the same serial number and base metadata but has a different `device_id` corresponding to the specific sensor capability. + +## Аналіз журналу польотів + +Device information is automatically logged to flight logs. +You can extract it using [pyulog](../log/flight_log_analysis.md#pyulog), though note that fields like vendor name, model name, and serial number are stored as `char` arrays and require additional parsing. + +## Дивіться також + +- [CAN (DroneCAN & Cyphal)](../can/index.md) — CAN bus configuration and setup +- [DroneCAN](../dronecan/index.md) — DroneCAN-specific documentation +- [Flight Log Analysis](../log/flight_log_analysis.md) — Flight log analysis diff --git a/docs/uk/dronecan/ark_g5_rtk_gps.md b/docs/uk/dronecan/ark_g5_rtk_gps.md new file mode 100644 index 0000000000..60bd410a64 --- /dev/null +++ b/docs/uk/dronecan/ark_g5_rtk_gps.md @@ -0,0 +1,112 @@ +# ARK G5 RTK GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band [RTK GPS](../gps_compass/rtk_gps.md). + +The module incorporates the [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-gps/) (US) + +## Характеристики обладнання + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- Датчики + - [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Кнопка безпеки +- Зумер +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED індикатори + - GPS Fix + - Статус RTK + - RGB Статус системи +- USA Built +- NDAA Compliant +- Вимоги до живлення + - 5V + - 270mA +- Розміри + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## Налаштування програмного забезпечення + +### Підключення + +The ARK G5 RTK GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Встановлення + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 Configuration](#px4-configuration). + +## Налаштування прошивки + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Налаштування польотного контролера + +### Увімкнення DroneCAN + +In order to use the ARK G5 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)). + +Кроки наступні: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK GPS CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### Конфігурація PX4 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK GPS from the vehicle's centre of gravity. + +## Значення LED індикаторів + +The GPS status lights are located to the right of the connectors: + +- Миготіння зеленого - це фіксація GPS +- Миготіння синього - це отримані корекції та RTK Float +- Сталий синій - це RTK зафіксовано + +## Дивіться також + +- [ARK G5 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/uk/dronecan/ark_g5_rtk_heading_gps.md b/docs/uk/dronecan/ark_g5_rtk_heading_gps.md new file mode 100644 index 0000000000..80e1d471e6 --- /dev/null +++ b/docs/uk/dronecan/ark_g5_rtk_heading_gps.md @@ -0,0 +1,150 @@ +# ARK G5 RTK HEADING GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK HEADING GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band dual antenna [RTK GPS](../gps_compass/rtk_gps.md) that additionally provides vehicle yaw information from GPS. + +The module incorporates the [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK HEADING GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-heading-gps/) (US) + +## Характеристики обладнання + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- Датчики + - [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Кнопка безпеки +- Зумер +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED індикатори + - GPS Fix + - Статус RTK + - RGB Статус системи +- USA Built +- NDAA Compliant +- Вимоги до живлення + - 5V + - 270mA +- Розміри + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## Налаштування програмного забезпечення + +### Підключення + +The ARK G5 RTK HEADING GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Встановлення + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Налаштування прошивки + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Налаштування польотного контролера + +### Увімкнення DroneCAN + +In order to use the ARK G5 RTK HEADING GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)). + +Кроки наступні: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK HEADING GPS CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### Конфігурація PX4 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK HEADING GPS from the vehicle's centre of gravity. + +### Parameter references + +This GPS is using ARK's private driver, the prameters below only exist on the firmware we ship the GPS with. You can set these params either in QGC or using the DroneCAN GUI Tool. + +#### SEP_OFFS_YAW (float) + +Heading offset angle for dual antenna GPS setups that support heading estimation. +Set this to 0 if the antennas are parallel to the forward-facing direction of the vehicle and the Rover/ANT2 antenna is in front. +The offset angle increases clockwise. +Set this to 90 if the ANT2 antenna is placed on the right side of the vehicle and the Moving Base/MAIN antenna is on the left side. + +- Default: 0 +- Min: -360 +- Max: 360 +- Unit: degree + +#### SEP_OFFS_PITCH (float) + +Vertical offsets can be compensated for by adjusting the Pitch offset. +Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. + +- Default: 0 +- Min: -90 +- Max: 90 +- Unit: degree + +#### SEP_OUT_RATE (enum) + +Configures the output rate for GNSS data messages. + +- -1: OnChange (Default) +- 50: 50 ms +- 100: 100 ms +- 200: 200 ms +- 500: 500 ms + +## Значення LED індикаторів + +The GPS status lights are located to the right of the connectors: + +- Миготіння зеленого - це фіксація GPS +- Миготіння синього - це отримані корекції та RTK Float +- Сталий синій - це RTK зафіксовано + +## Дивіться також + +- [ARK G5 RTK HEADING GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/uk/dronecan/index.md b/docs/uk/dronecan/index.md index fdc3ceb61d..14d8abc6c1 100644 --- a/docs/uk/dronecan/index.md +++ b/docs/uk/dronecan/index.md @@ -27,6 +27,8 @@ DroneCAN was previously known as UAVCAN v0 (or just UAVCAN). - Проводка менше складна, оскільки ви можете мати один шину для підключення всіх ваших ESC і інших периферійних пристроїв DroneCAN. - Налаштування стає простіше, оскільки ви налаштовуєте нумерацію ESC, обертаючи кожен двигун вручну. - Це дозволяє користувачам налаштовувати та оновлювати прошивку всіх пристроїв, підключених через CAN, централізовано через PX4. +- PX4 automatically tracks device information (vendor, model, versions, serial numbers) for maintenance and fleet management. + See [Asset Tracking](../debug/asset_tracking.md). ## Підтримуване обладнання diff --git a/docs/uk/features_fw/gain_compression.md b/docs/uk/features_fw/gain_compression.md index e05a214b12..1e97f1eb18 100644 --- a/docs/uk/features_fw/gain_compression.md +++ b/docs/uk/features_fw/gain_compression.md @@ -1,6 +1,6 @@ # Gain compression - + Automatic gain compression reduces the gains of the angular-rate PID whenever oscillations are detected. It monitors the angular-rate controller output through a band-pass filter to identify these oscillations. diff --git a/docs/uk/flight_controller/micoair743-lite.md b/docs/uk/flight_controller/micoair743-lite.md index 3d0f443d5f..d98d3a1d30 100644 --- a/docs/uk/flight_controller/micoair743-lite.md +++ b/docs/uk/flight_controller/micoair743-lite.md @@ -1,6 +1,6 @@ # MicoAir743-Lite - + :::warning PX4 не розробляє цей (або будь-який інший) автопілот. diff --git a/docs/uk/flight_controller/radiolink_pix6.md b/docs/uk/flight_controller/radiolink_pix6.md index 4363ca30dd..b7475d5202 100644 --- a/docs/uk/flight_controller/radiolink_pix6.md +++ b/docs/uk/flight_controller/radiolink_pix6.md @@ -1,6 +1,6 @@ # RadiolinkPIX6 Flight Controller - + :::warning PX4 не розробляє цей (або будь-який інший) автопілот. diff --git a/docs/uk/flight_controller/x-mav_ap-h743r1.md b/docs/uk/flight_controller/x-mav_ap-h743r1.md index cde4247aac..03f01f3ffd 100644 --- a/docs/uk/flight_controller/x-mav_ap-h743r1.md +++ b/docs/uk/flight_controller/x-mav_ap-h743r1.md @@ -1,6 +1,6 @@ -# AP-H743-R1 +# AP-H743-R1 Flight Controller - + :::warning PX4 не розробляє цей (або будь-який інший) автопілот. diff --git a/docs/uk/flight_modes_fw/hold.md b/docs/uk/flight_modes_fw/hold.md index 04e59fd4e6..7477482f66 100644 --- a/docs/uk/flight_modes_fw/hold.md +++ b/docs/uk/flight_modes_fw/hold.md @@ -2,11 +2,14 @@ -The _Hold_ flight mode causes the vehicle to loiter (circle) around its current GPS position and maintain its current altitude. +The _Hold_ flight mode causes the vehicle to loiter around its current GPS position and maintain its current altitude. + +The mode supports a [number of distinct loiter modes](#loiter-modes), which are triggered using different QGC controls or MAVLink commands. +These allow loitering with circular and figure 8 flight paths. :::tip _Hold mode_ can be used to pause a mission or to help you regain control of a vehicle in an emergency. -Зазвичай він активується за допомогою наперед заданого перемикача. +It is usually activated with a pre-programmed RC switch. ::: ::: info @@ -24,24 +27,80 @@ _Hold mode_ can be used to pause a mission or to help you regain control of a ve ::: -## Технічний підсумок +## Loiter modes -Літак кружляє навколо позиції утримання GPS на поточній висоті. -The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. +### Default Loiter -Рух стіків радіокерування ігнорується. +The aircraft circles around the position at which the mode was triggered and maintain its current altitude. +The loiter radius is set by the parameter [NAV_LOITER_RAD](#NAV_LOITER_RAD). +Note that if the vehicle altitude is below [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT), it will ascend to that minimum altitude before circling. -### Параметри +The default loiter mode is entered when you switch to Hold mode without explicitly specifying any loiter behaviour. +For example, if you switch to Hold mode using an RC switch, select **Hold** on the QGC flight mode selector, or activate the mode using the MAVLink [MAV_CMD_DO_SET_MODE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) command. + +### Orbit Loiter Mode + + + +The aircraft travels towards a _specified_ orbit center position, then circles it with a given direction and radius. + +This behaviour can be accessed in QGroundControl by clicking on the map in Fly view, selecting **Orbit at Location**, and configuring the radius. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) command. +Note that PX4 respects the specified centre point (`param5`, `param6`, `param7`), and the radius and direction (`param1`). +PX4 ignores `param3` (Yaw behaviour) and `param4` (Orbits). +The value of `param2` (velocity) is also ignored, but the speed can be controlled using the [MAV_CMD_DO_CHANGE_SPEED](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) command (constrained between `FW_AIRSPD_MAX` and `FW_AIRSPD_MIN`). +PX4 outputs orbit status using the [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) message. + +### Figure 8 Loiter Mode + + + +The aircraft flys towards the closest point on a specified figure 8 path and then follows it. +The path is defined by the figure 8 centre position, orientation, and radius of two circles. + +The feature is experimental, and is not present in PX4 firmware by default (on most flight controller boards). +It can be included by setting the `CONFIG_FIGURE_OF_EIGHT` key in the [PX4 board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) for your board and rebuilding. +For example, this is enabled on the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/auterion/fmu-v6s/default.px4board#L46) file for the `auterion/fmu-v6s` board. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) command (PX4 respects all the parameters). +PX4 outputs the figure 8 status using the [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) message. + +:::info +Figure 8 loitering is not currently supported by QGC: [QGC#12778: Need Support Figure of eight (8 figure) loitering by QGC](https://github.com/mavlink/qgroundcontrol/issues/12778). +::: + +Figure 8 loitering is also available in the simulator. +You can test it in [Gazebo](../sim_gazebo_gz/index.md) using a fixed wing frame: + +```sh +make px4_sitl gz_rc_cessna +``` + +## Параметри Поведінку режиму утримання можна налаштувати за допомогою наведених нижче параметрів. | Параметр | Опис | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | Радіус кола обертання. | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | Радіус кола обертання. | | [NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | Мінімальна висота для режиму очікування (транспортний засіб підніметься на цю висоту, якщо режим увімкнуто на меншій висоті). | +## MAVLink Commands + +The following commands are relevant to this mode: + +- [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) - Switch to Hold mode and start the specified [Orbit loiter](#orbit-loiter-mode). + Params 2 (velocity), 3 (yaw), 4 (orbits) are ignored. + [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) is emitted. +- [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) - Switch to Hold mode and start the specified [Figure 8 loiter](#figure-8-loiter-mode). + All params are respected. + [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) is emitted. + +Note, other commands may be supported. + ## Дивіться також -[Hold Mode (MC)](../flight_modes_mc/hold.md) +- [Hold Mode (MC)](../flight_modes_mc/hold.md) diff --git a/docs/uk/flight_modes_fw/takeoff.md b/docs/uk/flight_modes_fw/takeoff.md index 5c339fc6fc..9edfa564da 100644 --- a/docs/uk/flight_modes_fw/takeoff.md +++ b/docs/uk/flight_modes_fw/takeoff.md @@ -49,8 +49,8 @@ If the local position is invalid or becomes invalid while executing the takeoff, ::: info -- Takeoff towards a target position was added in . -- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . +- Takeoff towards a target position was added in . +- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . - QGroundControl does not support `MAV_CMD_NAV_TAKEOFF` (at time of writing). ::: diff --git a/docs/uk/gps_compass/rtk_gps.md b/docs/uk/gps_compass/rtk_gps.md index dd4310e8fd..4366911cb5 100644 --- a/docs/uk/gps_compass/rtk_gps.md +++ b/docs/uk/gps_compass/rtk_gps.md @@ -20,52 +20,59 @@ PX4 supports the [u-blox M8P](https://www.u-blox.com/en/product/neo-m8p), [u-blo Таблиця вказує пристрої, які також виводять курсову відмітку, а також можуть надавати курсову відмітку, коли використовуються дві одиниці на транспортному засобі. Він також відзначає пристрої, які підключаються через CAN шину, та ті, які підтримують PPK (пост-процесуальну кінематику). -| Пристрій | GPS | Компас | [DroneCAN](../dronecan/index.md) | [GPS Yaw](#configuring-gps-as-yaw-heading-source) | PPK | -| :------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------: | :------: | :------------------------------: | :-----------------------------------------------: | :-: | -| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | -| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna][SeptDualAnt] | | -| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | BMP390 | ✓ | | | -| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | -| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | -| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | -| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | -| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P](https://docs.datagnss.com/gnss/gnss_module/D10P_RTK) | IST8310 | | ✘ | | -| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | -| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | -| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | -| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | -| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | -| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna][UnicoreDualAnt] | | -| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | -| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | -| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | -| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | -| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | -| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | +| Пристрій | GPS | Компас | [DroneCAN] | [GPS Yaw] | PPK | +| :------------------------------------------------------------------------------------------------------------------- | :------------------: | :------: | :--------: | :---------------------------------: | :-: | +| [ARK G5 RTK GPS](../dronecan/ark_g5_rtk_gps.md) | [mosaic-G5 P3] | IIS2MDC | ✓ | | | +| [ARK G5 RTK HEADING GPS](../dronecan/ark_g5_rtk_heading_gps.md) | [mosaic-G5 P3H] | IIS2MDC | ✓ | [Heading Capability][mosaic-G5 P3H] | | +| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | +| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna] | | +| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | IIS2MDC | ✓ | | | +| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | +| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P] | | +| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P] | | +| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | +| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | +| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | +| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P] | | +| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P] | IST8310 | | ✘ | | +| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | +| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | +| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | +| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P] | | +| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P] | | +| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | +| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P] | | +| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | +| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna] | | +| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | +| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | +| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P] | | +| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | +| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | +| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | +| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P] | | +| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P] | | +| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | [RaccnLabL1L2ZED-F9P ext_ant]: https://docs.raccoonlab.co/guide/gps_mag_baro/gnss_external_antenna_f9p_v320.html [RaccoonLab L1/L2 ZED-F9P]: https://docs.raccoonlab.co/guide/gps_mag_baro/gps_l1_l2_zed_f9p.html -[DualF9P]: ../gps_compass/u-blox_f9p_heading.md -[SeptDualAnt]: ../gps_compass/septentrio.md#gnss-based-heading -[UnicoreDualAnt]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw +[Dual F9P]: ../gps_compass/u-blox_f9p_heading.md +[Septentrio Dual Antenna]: ../gps_compass/septentrio.md#gnss-based-heading +[Unicore Dual Antenna]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw [DATAGNSS GEM1305 RTK]: ../gps_compass/rtk_gps_gem1305.md +[DroneCAN]: ../dronecan/index.md +[GPS Yaw]: #configuring-gps-as-yaw-heading-source +[mosaic-G5 P3]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3 +[mosaic-G5 P3H]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H +[D10P]: https://docs.datagnss.com/gnss/gnss_module/D10P_RTK Примітки: @@ -145,6 +152,7 @@ This should be set by default, but if not, follow the [MAVLink2 configuration in ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) 4. Після завершення опитування: + - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) diff --git a/docs/uk/middleware/uxrce_dds.md b/docs/uk/middleware/uxrce_dds.md index 956a916341..9fe31af33d 100644 --- a/docs/uk/middleware/uxrce_dds.md +++ b/docs/uk/middleware/uxrce_dds.md @@ -332,9 +332,11 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable. Клієнтський модуль uXRCE-DDS може синхронізувати мітку часу повідомлень, якими обмінюються через міст. Це стандартна конфігурація. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled. - - [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX): Index-based namespace definition + - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. :::info Many ports are already have a default configuration. @@ -439,7 +441,7 @@ PX4_UXRCE_DDS_NS=uav_1 make px4_sitl gz_x500 ::: -- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. diff --git a/docs/uk/neural_networks/index.md b/docs/uk/neural_networks/index.md new file mode 100644 index 0000000000..016a8cbe0e --- /dev/null +++ b/docs/uk/neural_networks/index.md @@ -0,0 +1,21 @@ +# Neural Network Control + +PX4 supports the following mechanisms for using neural networks for multirotor control: + +- [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) — A generic neural network module that you can modify to use different underlying neural network and training models and compile into the firmware. +- [RAPTOR: A Neural Network Module for Adaptive Quadrotor Control](../neural_networks/raptor.md) — An adaptive RL NN module that works well with different Quad configurations without additional training. + +Generally you will select the former if you wish to experiment with custom neural network architectures and train them using PyTorch or TensorFlow, and the latter if you want to use a pre-trained neural-network controller that works out-of-the-box (without training for your particular platform) or if you train your own policies using [RLtools](https://rl.tools). + +Note that both modules are experimental and provided for experimentation. +The table below provides more detail on the differences. + +| Use Case | [`mc_raptor`](../neural_networks/raptor.md) | [`mc_nn_control`](../neural_networks/mc_neural_network_control.md) | +| ---------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ | +| Pre-trained policy that adapts to any quadrotor without training | ✓ RAPTOR | ✘ | +| Train policy in PyTorch/TF | ✘ | ✓ TF Lite | +| Train policy in RLtools | ✓ | ✘ | +| Use manual control (remote) with NN policy | ✘ GPS/MoCap | ✓ Manual attitude commands | +| Load policy checkpoints from SD card | ✓ Upload via MAVLink FTP | ✘ Compiled into firmware | +| Offboard setpoints | ✓ MAVLink | ✘ | +| Internal Trajectory Generator | ✓ (Position, Lissajous) | ✘ | diff --git a/docs/uk/neural_networks/mc_neural_network_control.md b/docs/uk/neural_networks/mc_neural_network_control.md new file mode 100644 index 0000000000..c0527480a1 --- /dev/null +++ b/docs/uk/neural_networks/mc_neural_network_control.md @@ -0,0 +1,119 @@ +# MC Neural Networks Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. +It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. + +The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](./tflm.md) module. +The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. +While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. +Note that after training the network you will need to update and rebuild PX4. + +TLFM is a mature inference library intended for use on embedded devices. +It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. +If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). + +This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. +The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. + +If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). + +## Neural Network PX4 Firmware + +:::warning +This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). +::: + +The module has been tested on a number of configurations, which can be build locally using the commands: + +```sh +make px4_sitl_neural +``` + +```sh +make px4_fmu-v6c_neural +``` + +```sh +make mro_pixracerpro_neural +``` + +You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: + +```sh +CONFIG_LIB_TFLM=y +CONFIG_MODULES_MC_NN_CONTROL=y +``` + +:::tip +The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. +::: + +## Example Module Overview + +The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: + +![neural_control](../../assets/advanced/neural_control.png) + +In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. +We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. +We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) + +### Вхід + +The input can be changed to whatever you want. +Set up the input you want to use during training and then provide the same input in PX4. +In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: + +- [3] Local position error. (goal position - current position) +- [6] The first 2 rows of a 3 dimensional rotation matrix. +- [3] Linear velocity +- [3] Angular velocity + +All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. +PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. +Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. + +![ENU-NED](../../assets/advanced/ENU-NED.png) + +ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. + +### Output + +The output consists of 4 values, the motor forces, one for each motor. +These are transformed in the `RescaleActions()` function. +This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. +So the output from the network needs to be normalized before they can be sent to the motors in PX4. + +The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. +The publishing is handled in `PublishOutput(float* command_actions)` function. + +:::tip +If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. +Decrease it for more thrust. +::: + +## Training your own Network + +The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). +But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. + +Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. +If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). + +You should do one system identification flight for this and get an approximate inertia matrix for your platform. +On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). + +Then do the following steps: + +- Do a hover flight +- Read of the logs what RPM is required for the drone to hover. +- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. +- Insert these values into the Aerial Gym configuration and train your network. +- Convert the network as explained in [TFLM](tflm.md). diff --git a/docs/uk/neural_networks/nn_module_utilities.md b/docs/uk/neural_networks/nn_module_utilities.md new file mode 100644 index 0000000000..c41a520cf6 --- /dev/null +++ b/docs/uk/neural_networks/nn_module_utilities.md @@ -0,0 +1,86 @@ +# Neural Network Module: System Integration + +The neural control module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) implements an end-to-end controller utilizing neural networks. + +The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](./tflm.md). +This page covers the changes that were made to integrate the module into PX4, both within the module, and in larger system configuration. + +:::tip +This topic should help you to shape the module to your own needs. + +You will need some familiarity with PX4 development. +For more information see the developer [Getting Started](../dev_setup/getting_started.md). +::: + +## Автозавантаження + +A line to autostart the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module has been added in the [`ROMFS/px4fmu_common/init.d/rc.mc_apps`](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rc.mc_apps) startup script. + +It checks whether the module is included by looking for the parameter [MC_NN_EN](../advanced_config/parameter_reference.md#MC_NN_EN). +If this is set to `1` (the default value), the module will be started when booting PX4. +Similarly you could create other parameters in the [`mc_nn_control_params.c`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/mc_nn_control_params.c) file for other startup script checks. + +## Custom Flight Mode + +The module creates its own flight mode "Neural Control" which lets you choose it from the flight mode menu in QGC and bind it to a switch on you RC controller. +This is done by using the [ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) internally. +This involves several steps and is visualized here: + +:::info +The module does not actually use ROS 2, it just uses the API exposed through uORB topics. +::: + +:::info +In some QGC versions the flight mode does not show up, so make sure to update to the newest version. +This only works for some flight controllers, so you might have to use an RC controller to switch to the correct external flight mode. +::: + +![neural_mode_registration](../../assets/advanced/neural_mode_registration.png) + +1. Publish a [RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md). + This specifies what you want to create, you can read more about this in the [Control Interface](../ros2/px4_ros2_control_interface.md). + In this case we register an arming check and a mode. +2. Wait for a [RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md). + This will give feedback on wether the mode registration was successful, and what the mode and arming check id is for the new mode. +3. [Optional] With the mode id, publish a [VehicleControlMode](../msg_docs/VehicleControlMode.md) message on the `config_control_setpoints` topic. + Here you can configure what other modules run in parallel. + The example controller replaces everything, so it turns off allocation. + If you want to replace other parts you can enable or disable the modules accordingly. +4. [Optional] With the mode id, publish a [ConfigOverrides](../msg_docs/ConfigOverrides.md) on the `config_overrides_request` topic. + (This is not done in the example module) This will let you defer failsafes or stop it from automatically disarming. +5. When the mode has been registered a [ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) will be sent, asking if your mode has everything it needs to run. + This message must be answered with a [ArmingCheckReply](../msg_docs/ArmingCheckReply.md) so the mode is not flagged as unresponsive. + In this response it is possible to set what requirements the mode needs to run, like local position. + If any of these requirements are set the commander will stop you from switching to the mode if they are not fulfilled. + It is also important to set health_component_index and num_events to 0 to not get a segmentation fault. + Unless you have a health component or events. +6. Listen to the [VehicleStatus](../msg_docs/VehicleStatus.md) topic. + If the nav_state equals the assigned `mode_id`, then the Neural Controller is activated. +7. When active the module will run the controller and publish to [ActuatorMotors](../msg_docs/ActuatorMotors.md). + If you want to replace a different part of the controller, you should find the appropriate topic to publish to. + +To see how the requests are handled you can check out [src/modules/commander/ModeManagement.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeManagement.cpp). + +## Логування + +To add module-specific logging a new topic has been added to [uORB](../middleware/uorb.md) called [NeuralControl](../msg_docs/NeuralControl.md). +The message definition is also added in `msg/CMakeLists.txt`, and to [`src/modules/logger/logged_topics.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/logger/logged_topics.cpp) under the debug category. +For these messages to be saved in your logs you need to include `debug` in the [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) parameter. + +## Timing + +The module has two includes for measuring the inference times. +The first one is a driver that works on the actual flight controller units, but a second one, `chrono`, is loaded for SITL testing. +Which timing library is included and used is based on wether PX4 is built with NUTTX or not. + +## Changing the setpoint + +The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message's position fields to define its target. +To follow a trajectory, you can send updated setpoints. +For an example of how to do this in a PX4 module, see the [mc_nn_testing](https://github.com/SindreMHegre/PX4-Autopilot-public/tree/main/src/modules/mc_nn_testing) module in this fork. +Note that this is not included in upstream PX4. +To use it, copy the module folder from the linked repository into your workspace, and enable it by adding the following line to your `.px4board` file: + +```sh +CONFIG_MODULES_MC_NN_TESTING=y +``` diff --git a/docs/uk/neural_networks/raptor.md b/docs/uk/neural_networks/raptor.md new file mode 100644 index 0000000000..7c031632c7 --- /dev/null +++ b/docs/uk/neural_networks/raptor.md @@ -0,0 +1,221 @@ +# RAPTOR: A Neural Network Module for Adaptive Quadrotor Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +RAPTOR is a tiny reinforcement-learning based neural network module for quadrotor control that can be used to control a wide variety of quadrotors without retuning. + +This topic provides an overview of the fundamental concepts, and explains how you can use the module in simulation and real hardware. + +## Загальний огляд + +![Visual Abstract](../../assets/advanced/neural_networks/raptor/visual_abstract.jpg) + +RAPTOR is an adaptive policy for end-to-end quadrotor control. +It is motivated by the human ability to adapt learned behaviours to similar situations. +For example, while humans may initially require many hours of driving experience to be able to smoothly control the car and blend into traffic, when faced with a new vehicle they do not need to re-learn how to drive — they only need to experience a few rough braking/acceleration/steering responses to adjust their previously learned behavior. + +Reinforcement Learning (RL) is a machine learning technique that uses trial and error to learn decision making/control behaviors, which is similar to the way that humans learn to drive. +RL is interesting for controlling robots (and particularly UAVs) because it overcomes some fundamental limitations of classic, modular control architectures (information loss at module boundaries, requirement for expert tuning, etc). +RL has been very successful in [high-performance quadrotor flight](https://doi.org/10.1038/s41586-023-06419-4), but previous designs have not been particularly adaptable to new frames and vehicle types. + +RAPTOR fills this gap and demonstrates a single, tiny neural-network control policy that can control a wide variety of quadrotors (tested on real quadrotors from 32 g to 2.4 kg). + +For more details please refer to this video: + + + +The method we developed for training the RAPTOR policy is called Meta-Imitation Learning: + +![Diagram showing the Method Overview](../../assets/advanced/neural_networks/raptor/method.jpg) + +You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: + + + +For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). + +## Структура + +The RAPTOR control policy is an end-to-end policy that takes position, orientation, linear velocity and angular velocity as inputs and outputs motor commands (`actuator_motors`). +To integrate it into PX4 we use the external mode registration facilities in PX4 (which also works well for internal modes as demonstrated in `mc_nn_control`). +Because of this architecture the `mc_raptor` module is completely decoupled from all other PX4 logic. + +By default, the RAPTOR module expects setpoints via `trajectory_setpoint` messages. +If no `trajectory_setpoint` messages are received or if no `trajectory_setpoint` is received within 200 ms, the current position and orientation (with zero velocity) is used as the setpoint. +Since feeding setpoints reliably via telemetry is still a challenge, we also implement a simple option to generate internal reference trajectories (controlled through the `MC_RAPTOR_INTREF` parameter) for demonstration and benchmarking purposes. + +## Функції + +- Tiny neural network (just 2084 parameters) => minimal CPU usage +- Easily maintainable + - Simple CMake setup + - Self-contained (no interference with other modules) + - Single, simple and well-maintained dependency (RLtools) +- Loading neural network parameters from SD card + - Minimal flash usage (for possible inclusion into default build configurations) + - Easy development: Train new neural network and just upload it via MAVLink FTP without requiring to re-flash the firmware +- Tested on 10+ different real platforms (including flexible frames, brushed motors) +- Actively developed and maintained + +## Використання + +### SITL + +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate + +```sh +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 # Enable the mc_raptor module +param save +``` + +Upload the RAPTOR checkpoint to the "SD card": Separate terminal + +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` + +Restart (Ctrl+C) + +```sh +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```sh +commander mode ext{RAPTOR_MODE_ID} +``` + +#### Internal Reference Trajectory Generation + +In our experience, feeding the `trajectory_setpoint` via MAVLink (even via WiFi telemetry) is unreliable. +But we do not want to constrain this module to only platforms that have a companion board. + +For this reason we have integrated a simple internal reference trajectory generator for testing and benchmarking purposes. +It supports position (constant position and yaw setpoint) as well as configurable [Lissajous trajectories](https://en.wikipedia.org/wiki/Lissajous_curve). + +The Lissajous generator can, for example, generate smooth figure-eight trajectories that contain interesting accelerations for benchmarking and testing purposes. +Please refer to the embedded configurator later in this section to explore the Lissajous parameters and view the resulting trajectories. + +To use the internal reference generator, select the mode: `0`: Off/activation position tracking, `1`: Lissajous + +```sh +param set MC_RAPTOR_INTREF 1 +``` + +Restart (ctrl+c) + +```sh +commander takeoff +commander mode ext{RAPTOR_MODE_ID} +mc_raptor intref lissajous 0.5 1 0 2 1 1 10 3 +``` + +The trajectory is relative to the position and yaw of the vehicle at the point where the RAPTOR mode is activated (or the position and yaw where the parameters are changed if it is already activated). + +You can adjust the parameters of the trajectory with the following tool. +Make sure to copy the generated CLI string at the end: + + + +### Real-World + +#### Установка + +The `mc_raptor` module has been mostly tested with the Holybro X500 V2 but it should also work out-of-the-box with other platforms (see the [Other Platforms](#other-platforms) section). + +```sh +make px4_fmu-v6c_raptor upload +``` + +We recommend initially testing the RAPTOR mode using a dead man's switch. +For this we configure the mode selection to be connected to a push button or a switch with a spring that automatically switches back. +In the default position we configure e.g. `Stabilized Mode` and in the pressed configuration we select `External Mode 1` (since the name of the external mode is only transmitted at runtime). +This allows to take off manually and then just trigger the RAPTOR mode for a split-second to see how it behaves. +In our experiments it has been exceptionally stable (zero crashes) but we still think progressively activating it for longer is the safest way to build confidence. + +:::warning +Make sure that your platform uses the standard PX4 quadrotor motor layout: + +1: front-right, 2: back-left, 3: front-left, 4: back-right +::: + +##### Other Platforms + +To enable the `mc_raptor` module in other platforms, just add `CONFIG_MODULES_MC_RAPTOR=y` and `CONFIG_LIB_RL_TOOLS=y` + +```diff ++++ b/boards/px4/fmu-v6c/raptor.px4board +@@ -35,2 +35,3 @@ + CONFIG_DRIVERS_UAVCAN=y ++CONFIG_LIB_RL_TOOLS=y + CONFIG_MODULES_AIRSPEED_SELECTOR=y +@@ -64,2 +65,3 @@ + CONFIG_MODULES_MC_POS_CONTROL=y ++CONFIG_MODULES_MC_RAPTOR=y + CONFIG_MODULES_MC_RATE_CONTROL=y +``` + +#### Results + +Even though there were moderate winds (~ 5 m/s) during the test, we found good figure-eight tracking performance at velocities up to 12 m/s: + +![Lissajous](../../assets/advanced/neural_networks/raptor/results_figure_eight.svg) + +We also tested the linear velocity in a straight line and found that the RAPTOR policy can reliably fly at > 17 m/s (the wind direction was orthogonal to the line): + +![Linear Oscillation](../../assets/advanced/neural_networks/raptor/results_line.svg) + +### Усунення проблем + +#### Логування + +Use this logging configuration to log all relevant topics at maximum rate: + +```sh +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` + +Use mavproxy FTP to upload it: + +```sh +mavproxy.py +``` + +##### Real + +```sh +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +##### SITL + +```sh +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/docs/uk/neural_networks/tflm.md b/docs/uk/neural_networks/tflm.md new file mode 100644 index 0000000000..85b61cb840 --- /dev/null +++ b/docs/uk/neural_networks/tflm.md @@ -0,0 +1,77 @@ +# TensorFlow Lite Micro (TFLM) + +The PX4 [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. + +This is a mature inference library intended for use on embedded devices, and is hence a suitable choice for PX4. + +This guide explains how the TFLM library is integrated into the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module, and the changes you would have to make to use it for your own neural network. + +:::tip +For more information, see the [TFLM guide](https://ai.google.dev/edge/litert/microcontrollers/get_started). +::: + +## TLMF NN Formats + +TFLM uses networks in its own [tflite format](https://ai.google.dev/edge/litert/models/convert). +However, since many microcontrollers do not have native filesystem support, a tflite file can be converted to a C++ source and header file. + +This is what is done in `mc_nn_control`. +The tflight neural network is represented in code by the files [`control_net.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.cpp) and [`control_net.hpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.hpp). + +### Getting a Network in tflite Format + +There are many online resource for generating networks in the `.tflite` format. + +For this example we trained the network in the open source [Aerial Gym Simulator](https://ntnu-arl.github.io/aerial_gym_simulator/). +Aerial Gym includes a guide, and supports RL both for control and vision-based navigation tasks. + +The project includes conversion code for `PyTorch -> TFLM` in the [resources/conversion](https://github.com/ntnu-arl/aerial_gym_simulator/tree/main/resources/conversion) folder. + +### Updating `mc_nn_control` with your own NN + +You can convert a `.tflite` network into a `.cc` file in the ubuntu terminal with this command: + +```sh +xxd -i converted_model.tflite > model_data.cc +``` + +You will then have to modify the `control_net.hpp` and `control_net.cpp` to include the data from `model_data.cc`: + +- Take the size of the network in the bottom of the `.cc` file and replace the size in `control_net.hpp`. +- Take the data in the model array in the `cc` file, and replace the ones in `control_net.cpp`. + +You are now ready to run your own network. + +## Code Explanation + +This section explains the code used to integrate the NN in `control_net.cpp`. + +### Operations and Resolver + +Firstly we need to create the resolver and load the needed operators to run inference on the NN. +This is done in the top of `mc_nn_control.cpp`. +The number in `MicroMutableOpResolver<3>` represents how many operations you need to run the inference. + +A full list of the operators can be found in the [micro_mutable_op_resolver.h](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/micro_mutable_op_resolver.h) file. +There are quite a few supported operators, but you will not find the most advanced ones. +In the control example the network is fully connected so we use `AddFullyConnected()`. +Then the activation function is ReLU, and we `AddAdd()` for the bias on each neuron. + +### Interpreter + +In the `InitializeNetwork()` we start by setting up the model that we loaded from the source and header file. +Next is to set up the interpreter, this code is taken from the TFLM documentation and is thoroughly explained there. +The end state is that the `_control_interpreter` is set up to later run inference with the `Invoke()` member function. +The `_input_tensor` is also defined, it is fetched from `_control_interpreter->input(0)`. + +### Вхідні дані + +The `_input_tensor` is filled in the `PopulateInputTensor()` function. +`_input_tensor` works by accessing the `->data.f` member array and fill in the required inputs for your network. +The inputs used in the control network is covered in [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md). + +### Виводи + +For the outputs the approach is fairly similar to the inputs. +After setting the correct inputs, calling the `Invoke()` function the outputs can be found by getting `_control_interpreter->output(0)`. +And from the output tensor you get the `->data.f` array. diff --git a/docs/uk/releases/1.16.md b/docs/uk/releases/1.16.md index 024c3e2fff..a60af13c90 100644 --- a/docs/uk/releases/1.16.md +++ b/docs/uk/releases/1.16.md @@ -151,6 +151,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### uXRCE-DDS / ROS2 - [PX4-Autopilot#24113](https://github.com/PX4/PX4-Autopilot/pull/24113): [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to translate PX4 messages from one definition version to another dynamically +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [ROS-based waypoint missions](../ros2/px4_ros2_waypoint_missions.md). - dds_topics: add vtol_vehicle_status ([PX4-Autopilot#24582](https://github.com/PX4/PX4-Autopilot/pull/24582)) - dds_topics: add home_position ([PX4-Autopilot#24583](https://github.com/PX4/PX4-Autopilot/pull/24583)) diff --git a/docs/uk/releases/1.17.md b/docs/uk/releases/1.17.md new file mode 100644 index 0000000000..5b388e69e0 --- /dev/null +++ b/docs/uk/releases/1.17.md @@ -0,0 +1,134 @@ +# PX4-Autopilot v1.17.0 Release Notes + + + + + +
+
+

This page is on a release branch, and hence probably out of date. See the latest version.

+
+
+ +This contains changes to PX4 planned for PX4 v1.17 (since the last major release [PX v1.16](../releases/1.16.md)). + +:::warning +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in PX4 v1.17 release. +New features that are not expected to go into the v1.17 release are in [PX4-Autopilot `main` Release Notes](../releases/main.md). +::: + +## Прочитайте перед оновленням + +TBD … + +Please continue reading for [upgrade instructions](#upgrade-guide). + +## Основні зміни + +- Уточнюється + +## Інструкції для оновлення + +## Інші зміни + +### Підтримка обладнання + +- **[New Hardware]** boards: [MicoAir743-Lite FC](../flight_controller/micoair743-lite.md) +- **[New Hardware]** boards: [RadiolinkPIX6 FC](../flight_controller/radiolink_pix6.md) +- **[New Hardware]** boards: [AP-H743-R1 FC](../flight_controller/x-mav_ap-h743r1.md) + + + +### Управління + + + +- [MC Neural Network Module](../advanced/neural_networkss.md) + +### Оцінки + +- Уточнюється + + + +### Симуляція + +- Overhaul rover simulation: + - Add synthetic differential rover model: [PX4-gazebo-models#107](https://github.com/PX4/PX4-gazebo-models/pull/107) + - Add synthetic mecanum rover model: [PX4-gazebo-models#113](https://github.com/PX4/PX4-gazebo-models/pull/113) + - Update synthetic ackermann rover model: [PX4-gazebo-models#117](https://github.com/PX4/PX4-gazebo-models/pull/117) + +- [Simulation-in-Hardware (SIH)](../sim_sih/index.md#compatibility) + - New simulation: MC Hexacopter X + - New simulation: Ackermann Rover + +### Debug & Logging + +- Уточнюється + +### Ethernet + +- Уточнюється + +### uXRCE-DDS / Zenoh / ROS2 + +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [Fixed Wing lateral/longitudinal setpoint](../ros2/px4_ros2_control_interface.md#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype) (`FwLateralLongitudinalSetpointType`) and [VTOL transitions](../ros2/px4_ros2_control_interface.md#controlling-a-vtol). ([PX4-Autopilot#24056](https://github.com/PX4/PX4-Autopilot/pull/24056)). +- [UXRCE_DDS: Simple index based namespace (UXRCE_DDS_NS_IDX)](../middleware/uxrce_dds.md#customizing-the-namespace) +- [Zenoh (PX4 ROS 2 rmw_zenoh)](../middleware/zenoh.md) + +### MAVLink + +- Уточнюється + + + +### VTOL + +- Уточнюється + +### Літак з фіксованим крилом + +- [Fixed Wing Takeoff mode](../flight_modes_fw/takeoff.md) will now keep climbing with level wings on position loss. + A target takeoff waypoint can be set to control takeoff course and loiter altitude. ([PX4-Autopilot#25083](https://github.com/PX4/PX4-Autopilot/pull/25083)). +- Automatically suppress angular rate oscillations using [Gain compression](../features_fw/gain_compression.md). ([PX4-Autopilot#25840: FW rate control: add gain compression algorithm](https://github.com/PX4/PX4-Autopilot/pull/25840)) + +### Ровер + +- Removed deprecated rover module ([PX4-Autopilot#25054](https://github.com/PX4/PX4-Autopilot/pull/25054)). +- Add support for [Apps & API](../flight_modes_rover/api.md) including [Rover Setpoints](../ros2/px4_ros2_control_interface.md#rover-setpoints) ([PX4-Autopilot#25074](https://github.com/PX4/PX4-Autopilot/pull/25074), [PX4-ROS2-Interface-Lib#140](https://github.com/Auterion/px4-ros2-interface-lib/pull/140)). +- Update [rover simulation](../frames_rover/index.md#simulation) ([PX4-Autopilot#25644](https://github.com/PX4/PX4-Autopilot/pull/25644)) (see [Simulation](#simulation) release note for details). + +### ROS 2 + +- Уточнюється diff --git a/docs/uk/releases/index.md b/docs/uk/releases/index.md index 32ee1a8d77..260fd67bc7 100644 --- a/docs/uk/releases/index.md +++ b/docs/uk/releases/index.md @@ -2,7 +2,8 @@ Перелік PX4 реліз, вони містять список змін, що відбулися в кожному релізі, пояснення включених функцій, виправлень, застарілих та оновлень. -- [main](../releases/main.md) (changes since v1.16) +- [main](../releases/main.md) (changes planned for v1.18 or later) +- [v1.17](../releases/1.17.md) (changes planned for v1.17, since v1.16) - [v1.16](../releases/1.16.md) - [v1.15](../releases/1.15.md) - [v1.14](../releases/1.14.md) diff --git a/docs/uk/releases/main.md b/docs/uk/releases/main.md index 8919008edf..835589598a 100644 --- a/docs/uk/releases/main.md +++ b/docs/uk/releases/main.md @@ -16,13 +16,13 @@ const { site } = useData(); This contains changes to PX4 `main` branch since the last major release ([PX v1.16](../releases/1.16.md)). :::warning -PX4 v1.16 is in candidate-release testing, pending release. -Update these notes with features that are going to be in `main` but not the PX4 v1.16 release. +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in `main` (PX4 v1.18 or later) but not the PX4 v1.17 release. ::: ## Прочитайте перед оновленням -TBD … +- TBD … Please continue reading for [upgrade instructions](#upgrade-guide). @@ -45,8 +45,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Управління - Added new flight mode(s): [Altitude Cruise (MC)](../flight_modes_mc/altitude_cruise.md), Altitude Cruise (FW). - For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. (PX4-Autopilot#25435: Add new flight mode: Altitude Cruise - ). + For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### Оцінки @@ -59,19 +58,34 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Симуляція +- Уточнюється + + + +### Debug & Logging + +- [Asset Tracking](../debug/asset_tracking.md): Automatic tracking and logging of external device information including vendor name, firmware and hardware version, serial numbers. Currently supports DroneCAN devices. ([PX4-Autopilot#25617](https://github.com/PX4/PX4-Autopilot/pull/25617)) + ### Ethernet - Уточнюється -### uXRCE-DDS / ROS2 +### uXRCE-DDS / Zenoh / ROS2 + +- Уточнюється + + ### MAVLink @@ -92,16 +106,26 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Літак з фіксованим крилом +- Уточнюється + + ### Ровер +- Уточнюється + + + ### ROS 2 - Уточнюється diff --git a/docs/uk/ros2/px4_ros2_control_interface.md b/docs/uk/ros2/px4_ros2_control_interface.md index 0905f468a6..13252a0f57 100644 --- a/docs/uk/ros2/px4_ros2_control_interface.md +++ b/docs/uk/ros2/px4_ros2_control_interface.md @@ -346,9 +346,9 @@ private: Наступні розділи надають список підтримуваних типів установок: - [MulticopterGotoSetpointType](#go-to-setpoint-multicoptergotosetpointtype): Smooth position and (optionally) heading control -- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics +- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics - DirectActuatorsSetpointType: Пряме керування моторами та установками сервоприводів польотних поверхонь -- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). +- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). :::tip The other setpoint types are currently experimental, and can be found in: [px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental). @@ -415,7 +415,7 @@ _goto_setpoint->update( #### Fixed-Wing Lateral and Longitudinal Setpoint (FwLateralLongitudinalSetpointType) - + :::info This setpoint type is supported for fixed-wing vehicles and for VTOLs in fixed-wing mode. @@ -557,7 +557,7 @@ and [`FW_THR_MAX`](../advanced_config/parameter_reference.md#FW_THR_MAX). #### Rover Setpoints - + The rover modules use a hierarchical structure to propagate setpoints: @@ -591,7 +591,7 @@ An example for a rover specific drive mode using the `RoverSpeedAttitudeSetpoint ### Controlling a VTOL - + To control a VTOL in an external flight mode, ensure you're returning the correct setpoint type based on the current flight configuration: diff --git a/docs/uk/sim_sih/index.md b/docs/uk/sim_sih/index.md index 6333fe0819..e94df82509 100644 --- a/docs/uk/sim_sih/index.md +++ b/docs/uk/sim_sih/index.md @@ -27,8 +27,8 @@ The Desktop computer is only used to display the virtual vehicle. - SIH for FW (airplane) and VTOL tailsitter are supported from PX4 v1.13. - SIH як SITL (без апаратного забезпечення) з версії PX4 v1.14. - SIH for Standard VTOL from PX4 v1.16. -- SIH for MC Hexacopter X from `main` (expected to be PX4 v1.17). -- SIH for Ackermann Rover from `main`. +- SIH for MC Hexacopter X from PX4 v1.17. +- SIH for Ackermann Rover from PX4 v1.17. ### Переваги From 05517935dcaf7fe779627eb88095f36da63db1c7 Mon Sep 17 00:00:00 2001 From: PX4 Build Bot Date: Wed, 28 Jan 2026 16:43:34 +1100 Subject: [PATCH 04/71] New Crowdin translations - ko (#26246) Co-authored-by: Crowdin Bot --- docs/ko/SUMMARY.md | 12 +- docs/ko/advanced/gimbal_control.md | 2 +- docs/ko/advanced/neural_networks.md | 120 +--------- docs/ko/can/index.md | 4 + docs/ko/config/safety.md | 26 +-- docs/ko/debug/asset_tracking.md | 68 ++++++ docs/ko/dronecan/ark_g5_rtk_gps.md | 112 +++++++++ docs/ko/dronecan/ark_g5_rtk_heading_gps.md | 150 ++++++++++++ docs/ko/dronecan/index.md | 2 + docs/ko/features_fw/gain_compression.md | 2 +- docs/ko/flight_controller/micoair743-lite.md | 2 +- docs/ko/flight_controller/radiolink_pix6.md | 2 +- docs/ko/flight_controller/x-mav_ap-h743r1.md | 6 +- docs/ko/flight_modes_fw/hold.md | 77 +++++- docs/ko/flight_modes_fw/takeoff.md | 4 +- docs/ko/gps_compass/rtk_gps.md | 88 +++---- docs/ko/middleware/uxrce_dds.md | 6 +- docs/ko/neural_networks/index.md | 21 ++ .../mc_neural_network_control.md | 119 ++++++++++ .../ko/neural_networks/nn_module_utilities.md | 86 +++++++ docs/ko/neural_networks/raptor.md | 221 ++++++++++++++++++ docs/ko/neural_networks/tflm.md | 77 ++++++ docs/ko/releases/1.16.md | 1 + docs/ko/releases/1.17.md | 134 +++++++++++ docs/ko/releases/index.md | 3 +- docs/ko/releases/main.md | 36 ++- docs/ko/ros2/px4_ros2_control_interface.md | 10 +- docs/ko/sim_sih/index.md | 4 +- 28 files changed, 1184 insertions(+), 211 deletions(-) create mode 100644 docs/ko/debug/asset_tracking.md create mode 100644 docs/ko/dronecan/ark_g5_rtk_gps.md create mode 100644 docs/ko/dronecan/ark_g5_rtk_heading_gps.md create mode 100644 docs/ko/neural_networks/index.md create mode 100644 docs/ko/neural_networks/mc_neural_network_control.md create mode 100644 docs/ko/neural_networks/nn_module_utilities.md create mode 100644 docs/ko/neural_networks/raptor.md create mode 100644 docs/ko/neural_networks/tflm.md create mode 100644 docs/ko/releases/1.17.md diff --git a/docs/ko/SUMMARY.md b/docs/ko/SUMMARY.md index 300979c54d..7f08297636 100644 --- a/docs/ko/SUMMARY.md +++ b/docs/ko/SUMMARY.md @@ -128,6 +128,7 @@ - [LED 신호 정의](getting_started/led_meanings.md) - [알람 소리 정의](getting_started/tunes.md) - [QGroundControl Flight-Readiness Status](flying/pre_flight_checks.md) + - [Asset Tracking](debug/asset_tracking.md) - [Hardware Selection & Setup](hardware/drone_parts.md) - [비행 컨트롤러 (오토파일럿)](flight_controller/index.md) @@ -273,6 +274,8 @@ - [Holybro M8N & M9N GPS](gps_compass/gps_holybro_m8n_m9n.md) - [Sky-Drones SmartAP GPS](gps_compass/gps_smartap.md) - [RTK GNSS](gps_compass/rtk_gps.md) + - [ARK G5 RTK GPS](dronecan/ark_g5_rtk_gps.md) + - [ARK G5 RTK HEADING GPS](dronecan/ark_g5_rtk_heading_gps.md) - [ARK RTK GPS (CAN)](dronecan/ark_rtk_gps.md) - [ARK RTK GPS L1 L5 (CAN)](dronecan/ark_rtk_gps_l1_l2.md) - [ARK X20 RTK GPS (CAN)](dronecan/ark_x20_rtk_gps.md) @@ -840,9 +843,11 @@ - [Camera Integration/Architecture](camera/camera_architecture.md) - [컴퓨터 비전](advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](tutorials/motion-capture.md) - - [Neural Networks](advanced/neural_networks.md) - - [Neural Network Module Utilities](advanced/nn_module_utilities.md) - - [TensorFlow Lite Micro (TFLM)](advanced/tflm.md) + - [Neural Networks](neural_networks/index.md) + - [MC NN Control Module (Generic)](neural_networks/mc_neural_network_control.md) + - [Neural Network Module Utilities](neural_networks/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](neural_networks/tflm.md) + - [RAPTOR Adaptive RL NN Module](neural_networks/raptor.md) - [Intel RealSense R200용 드라이버 설치](advanced/realsense_intel_driver.md) - [상태 추정기 전환](advanced/switching_state_estimators.md) - [트리 외부 모듈](advanced/out_of_tree_modules.md) @@ -925,6 +930,7 @@ - [출시](releases/index.md) - [main (alpha)](releases/main.md) + - [1.17 (alpha)](releases/1.17.md) - [1.16 (stable)](releases/1.16.md) - [1.15](releases/1.15.md) - [1.14](releases/1.14.md) diff --git a/docs/ko/advanced/gimbal_control.md b/docs/ko/advanced/gimbal_control.md index 1f40184d39..e0d9495f5f 100644 --- a/docs/ko/advanced/gimbal_control.md +++ b/docs/ko/advanced/gimbal_control.md @@ -74,7 +74,7 @@ For example, you might have the following settings to assign the gimbal roll, pi ![Gimbal Actuator config](../../assets/config/actuators/qgc_actuators_gimbal.png) -The PWM values to use for the disarmed, maximum and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low and high position in the slider. +The PWM values to use for the disarmed, maximum, center and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low, center and high position in the slider. The values may also be provided in gimbal documentation. ## Gimbal Control in Missions diff --git a/docs/ko/advanced/neural_networks.md b/docs/ko/advanced/neural_networks.md index 72b1fcb899..039259fd5f 100644 --- a/docs/ko/advanced/neural_networks.md +++ b/docs/ko/advanced/neural_networks.md @@ -1,119 +1 @@ -# Neural Networks - - - -:::warning -This is an experimental module. -Use at your own risk. -::: - -The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. -It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. - -The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md) module. -The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. -While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. -Note that after training the network you will need to update and rebuild PX4. - -TLFM is a mature inference library intended for use on embedded devices. -It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. -If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). - -This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. -The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. - -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). - -## Neural Network PX4 Firmware - -:::warning -This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). -::: - -The module has been tested on a number of configurations, which can be build locally using the commands: - -```sh -make px4_sitl_neural -``` - -```sh -make px4_fmu-v6c_neural -``` - -```sh -make mro_pixracerpro_neural -``` - -You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: - -```sh -CONFIG_LIB_TFLM=y -CONFIG_MODULES_MC_NN_CONTROL=y -``` - -:::tip -The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. -::: - -## Example Module Overview - -The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: - -![neural_control](../../assets/advanced/neural_control.png) - -In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. -We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. -We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) - -### Input - -The input can be changed to whatever you want. -Set up the input you want to use during training and then provide the same input in PX4. -In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: - -- [3] Local position error. (goal position - current position) -- [6] The first 2 rows of a 3 dimensional rotation matrix. -- [3] Linear velocity -- [3] Angular velocity - -All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. -PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. -Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. - -![ENU-NED](../../assets/advanced/ENU-NED.png) - -ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. - -### 출력 - -The output consists of 4 values, the motor forces, one for each motor. -These are transformed in the `RescaleActions()` function. -This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. -So the output from the network needs to be normalized before they can be sent to the motors in PX4. - -The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. -The publishing is handled in `PublishOutput(float* command_actions)` function. - -:::tip -If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. -Decrease it for more thrust. -::: - -## Training your own Network - -The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). -But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. - -Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. -If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). - -You should do one system identification flight for this and get an approximate inertia matrix for your platform. -On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). - -Then do the following steps: - -- Do a hover flight -- Read of the logs what RPM is required for the drone to hover. -- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. -- Insert these values into the Aerial Gym configuration and train your network. -- Convert the network as explained in [TFLM](tflm.md). + diff --git a/docs/ko/can/index.md b/docs/ko/can/index.md index ee516e9c6c..d628ee0ede 100644 --- a/docs/ko/can/index.md +++ b/docs/ko/can/index.md @@ -10,6 +10,10 @@ CAN it is designed to be democratic and uses differential signaling. For this reason it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. CAN also allows status feedback from peripherals and convenient firmware upgrades over the bus. +PX4 has the ability to track and log detailed information from CAN devices, including firmware versions, hardware versions, and serial numbers. +This enables unique identification and lifecycle tracking of hardware connected to the flight controller. +See [Asset Tracking](../debug/asset_tracking.md) for more information. + PX4 supports two software protocols for communicating with CAN devices: - [DroneCAN](../dronecan/index.md): PX4 recommends this for most common setups. diff --git a/docs/ko/config/safety.md b/docs/ko/config/safety.md index 0debe65eb2..d84dc6633a 100644 --- a/docs/ko/config/safety.md +++ b/docs/ko/config/safety.md @@ -121,36 +121,32 @@ PX4 and the receiver may also need to be configured in order to _detect RC loss_ ![Safety - RC Loss (QGC)](../../assets/qgc/setup/safety/safety_rc_loss.png) -The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [RC Loss timeout](#COM_RC_LOSS_T). -Users that want to disable the RC loss failsafe in specific automatic modes (mission, hold, offboard) can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). +The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [manual control loss timeout](#COM_RC_LOSS_T). +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). Additional (and underlying) parameter settings are shown below. | 매개변수 | 설정 | 설명 | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Manual Control Loss Timeout | Time after last setpoint received from the selected manual control source after which manual control is considered lost. This must be kept short because the vehicle will continue to fly using the old manual control setpoint until the timeout triggers. | +| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Manual Control Loss Timeout | Time after last setpoint received from the selected manual control source after which manual control is considered lost. This must be kept short because the vehicle will continue to fly using the last known stick position until the timeout triggers. | | [COM_FAIL_ACT_T](../advanced_config/parameter_reference.md#COM_FAIL_ACT_T) | Failsafe Reaction Delay | Delay in seconds between failsafe condition being triggered (`COM_RC_LOSS_T`) and failsafe action (RTL, Land, Hold). In this state the vehicle waits in hold mode for the manual control source to reconnect. This might be set longer for long-range flights so that intermittent connection loss doesn't immediately invoke the failsafe. It can be to zero so that the failsafe triggers immediately. | | [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | 안전장치 동작 | Disabled, Loiter, Return, Land, Disarm, Terminate. | -| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC 손실 예외 | Set the modes in which manual control loss is ignored: Mission, Hold, Offboard. | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC 손실 예외 | Set modes in which manual control loss is ignored. | ## 데이터 연결불량 안전장치 -The Data Link Loss failsafe is triggered if a telemetry link (connection to ground station) is lost. +The Data Link Loss failsafe is triggered if the connection to the last MAVLink ground station like QGroundControl is lost. +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_DLL_EXCEPT](#COM_DLL_EXCEPT). ![Safety - Data Link Loss (QGC)](../../assets/qgc/setup/safety/safety_data_link_loss.png) 설정에 관련된 기본 매개변수는 다음과 같습니다. -| 설정 | 매개변수 | 설명 | -| -------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -| 데이터 연결불량 시간 초과 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 데이터 연결이 끊어진 후 안전 장치가 동작하기 전까지의 시간입니다. | -| 안전장치 동작 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | - -다음 설정도 가능하지만 QGC UI에 표시되지 않습니다. - -| 설정 | 매개변수 | 설명 | -| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes where DL loss will not trigger a failsafe. | +| 설정 | 매개변수 | 설명 | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| 데이터 연결불량 시간 초과 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 데이터 연결이 끊어진 후 안전 장치가 동작하기 전까지의 시간입니다. | +| 안전장치 동작 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | +| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes in which data link loss is ignored. | ## Geofence 안전장치 diff --git a/docs/ko/debug/asset_tracking.md b/docs/ko/debug/asset_tracking.md new file mode 100644 index 0000000000..31461d4a29 --- /dev/null +++ b/docs/ko/debug/asset_tracking.md @@ -0,0 +1,68 @@ +# Asset Tracking + + + +PX4 can track and log detailed information about external hardware devices connected to the flight controller. +This enables unique identification of vehicle parts throughout their operational lifetime using device IDs, serial numbers, and version information. + +:::info +Asset tracking is currently implemented for [DroneCAN](../dronecan/index.md) devices only. +::: + +## 개요 + +Asset tracking allows you to determine exactly which hardware is installed on a vehicle, providing serial number, version, and other information. +This makes it easier to track and maintain specific vehicle parts across multiple vehicles, to quickly see what versions you're running when debugging, and log component information for regulatory audits. + +Asset tracking automatically collects and logs the following metadata from external devices: + +- **Device identification**: Vendor name, model name, device type +- **Version information**: Firmware version, hardware version +- **Unique identifiers**: Serial number, device ID +- **Device capabilities**: ESC, GPS, magnetometer, barometer, etc. + +This information is published via the [`device_information`](../msg_docs/DeviceInformation.md) uORB topic and logged to flight logs. +This enables fleet management, maintenance tracking, and troubleshooting. + +## Viewing Device Information + +### Real-Time Monitoring + +You can view device information in real-time using the [MAVLink Shell](../debug/mavlink_shell.md) or console: + +```sh +listener device_information +``` + +Example output for a CAN GPS module: + +```plain +TOPIC: device_information + device_information + timestamp: 16258961403 (0.216525 seconds ago) + device_id: 8944643 (Type: 0x88, UAVCAN:0 (0x7C)) + device_type: 5 + vendor_name: "cubepilot" + model_name: "here4" + firmware_version: "1.14.3006590" + hardware_version: "4.19" + serial_number: "1c00410018513331" +``` + +Device information is published in a round-robin fashion for each detected device, at a rate of approximately 1 Hz. + +### Multi-Capability Devices + +Devices with multiple sensors (e.g., a CAN GPS/magnetometer combo module like the HERE4) register separate device information entries for each capability. +Each entry shares the same serial number and base metadata but has a different `device_id` corresponding to the specific sensor capability. + +## 비행 로그 분석 + +Device information is automatically logged to flight logs. +You can extract it using [pyulog](../log/flight_log_analysis.md#pyulog), though note that fields like vendor name, model name, and serial number are stored as `char` arrays and require additional parsing. + +## See Also + +- [CAN (DroneCAN & Cyphal)](../can/index.md) — CAN bus configuration and setup +- [DroneCAN](../dronecan/index.md) — DroneCAN-specific documentation +- [Flight Log Analysis](../log/flight_log_analysis.md) — Flight log analysis diff --git a/docs/ko/dronecan/ark_g5_rtk_gps.md b/docs/ko/dronecan/ark_g5_rtk_gps.md new file mode 100644 index 0000000000..92ab020b62 --- /dev/null +++ b/docs/ko/dronecan/ark_g5_rtk_gps.md @@ -0,0 +1,112 @@ +# ARK G5 RTK GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band [RTK GPS](../gps_compass/rtk_gps.md). + +The module incorporates the [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 센서 + - [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 부저 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 크기 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 하드웨어 설정 + +### 배선 + +The ARK G5 RTK GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### 장착 + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 Configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)). + +단계는 다음과 같습니다: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 설정 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK GPS from the vehicle's centre of gravity. + +## LED 신호의 의미 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## See Also + +- [ARK G5 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/ko/dronecan/ark_g5_rtk_heading_gps.md b/docs/ko/dronecan/ark_g5_rtk_heading_gps.md new file mode 100644 index 0000000000..3b019a9b96 --- /dev/null +++ b/docs/ko/dronecan/ark_g5_rtk_heading_gps.md @@ -0,0 +1,150 @@ +# ARK G5 RTK HEADING GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK HEADING GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band dual antenna [RTK GPS](../gps_compass/rtk_gps.md) that additionally provides vehicle yaw information from GPS. + +The module incorporates the [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK HEADING GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-heading-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 센서 + - [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 부저 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 크기 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 하드웨어 설정 + +### 배선 + +The ARK G5 RTK HEADING GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### 장착 + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK HEADING GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)). + +단계는 다음과 같습니다: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK HEADING GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 설정 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK HEADING GPS from the vehicle's centre of gravity. + +### Parameter references + +This GPS is using ARK's private driver, the prameters below only exist on the firmware we ship the GPS with. You can set these params either in QGC or using the DroneCAN GUI Tool. + +#### SEP_OFFS_YAW (float) + +Heading offset angle for dual antenna GPS setups that support heading estimation. +Set this to 0 if the antennas are parallel to the forward-facing direction of the vehicle and the Rover/ANT2 antenna is in front. +The offset angle increases clockwise. +Set this to 90 if the ANT2 antenna is placed on the right side of the vehicle and the Moving Base/MAIN antenna is on the left side. + +- Default: 0 +- Min: -360 +- Max: 360 +- Unit: degree + +#### SEP_OFFS_PITCH (float) + +Vertical offsets can be compensated for by adjusting the Pitch offset. +Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. + +- Default: 0 +- Min: -90 +- Max: 90 +- Unit: degree + +#### SEP_OUT_RATE (enum) + +Configures the output rate for GNSS data messages. + +- -1: OnChange (Default) +- 50: 50 ms +- 100: 100 ms +- 200: 200 ms +- 500: 500 ms + +## LED 신호의 의미 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## See Also + +- [ARK G5 RTK HEADING GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/ko/dronecan/index.md b/docs/ko/dronecan/index.md index 1ce5c098a7..8b6738922d 100644 --- a/docs/ko/dronecan/index.md +++ b/docs/ko/dronecan/index.md @@ -27,6 +27,8 @@ Connecting peripherals over DroneCAN has many benefits: - Wiring is less complicated as you can have a single bus for connecting all your ESCs and other DroneCAN peripherals. - Setup is easier as you configure ESC numbering by manually spinning each motor. - It allows users to configure and update the firmware of all CAN-connected devices centrally through PX4. +- PX4 automatically tracks device information (vendor, model, versions, serial numbers) for maintenance and fleet management. + See [Asset Tracking](../debug/asset_tracking.md). ## 지원 하드웨어 diff --git a/docs/ko/features_fw/gain_compression.md b/docs/ko/features_fw/gain_compression.md index 87765c3c6d..855e64c08b 100644 --- a/docs/ko/features_fw/gain_compression.md +++ b/docs/ko/features_fw/gain_compression.md @@ -1,6 +1,6 @@ # Gain compression - + Automatic gain compression reduces the gains of the angular-rate PID whenever oscillations are detected. It monitors the angular-rate controller output through a band-pass filter to identify these oscillations. diff --git a/docs/ko/flight_controller/micoair743-lite.md b/docs/ko/flight_controller/micoair743-lite.md index af6032f040..2bf4b980a0 100644 --- a/docs/ko/flight_controller/micoair743-lite.md +++ b/docs/ko/flight_controller/micoair743-lite.md @@ -1,6 +1,6 @@ # MicoAir743-Lite - + :::warning PX4 does not manufacture this (or any) autopilot. diff --git a/docs/ko/flight_controller/radiolink_pix6.md b/docs/ko/flight_controller/radiolink_pix6.md index 4fe686a8b7..ab54385075 100644 --- a/docs/ko/flight_controller/radiolink_pix6.md +++ b/docs/ko/flight_controller/radiolink_pix6.md @@ -1,6 +1,6 @@ # RadiolinkPIX6 Flight Controller - + :::warning PX4 does not manufacture this (or any) autopilot. diff --git a/docs/ko/flight_controller/x-mav_ap-h743r1.md b/docs/ko/flight_controller/x-mav_ap-h743r1.md index 2e4c40c566..a7968d946c 100644 --- a/docs/ko/flight_controller/x-mav_ap-h743r1.md +++ b/docs/ko/flight_controller/x-mav_ap-h743r1.md @@ -1,6 +1,6 @@ -# AP-H743-R1 +# AP-H743-R1 Flight Controller - + :::warning PX4 does not manufacture this (or any) autopilot. @@ -25,7 +25,7 @@ It brings you ultimate performance, stability, and reliability in every aspect. - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM - 내장 센서 : - Accel/Gyro: ICM-42688-P\*2(Version1), BMI270\*2(Version2) - - 자력계: QMC5883P + - Mag: QMC5883P - Barometer: DPS310(Version1),SPL06(Version2) ### 인터페이스 diff --git a/docs/ko/flight_modes_fw/hold.md b/docs/ko/flight_modes_fw/hold.md index 9555a4f13e..6ee1566e5b 100644 --- a/docs/ko/flight_modes_fw/hold.md +++ b/docs/ko/flight_modes_fw/hold.md @@ -2,11 +2,14 @@ -The _Hold_ flight mode causes the vehicle to loiter (circle) around its current GPS position and maintain its current altitude. +The _Hold_ flight mode causes the vehicle to loiter around its current GPS position and maintain its current altitude. + +The mode supports a [number of distinct loiter modes](#loiter-modes), which are triggered using different QGC controls or MAVLink commands. +These allow loitering with circular and figure 8 flight paths. :::tip _Hold mode_ can be used to pause a mission or to help you regain control of a vehicle in an emergency. -It is usually activated with a pre-programmed switch. +It is usually activated with a pre-programmed RC switch. ::: ::: info @@ -24,24 +27,80 @@ It is usually activated with a pre-programmed switch. ::: -## Technical Summary +## Loiter modes -The aircraft circles around the GPS hold position at the current altitude. -The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. +### Default Loiter -RC stick movement is ignored. +The aircraft circles around the position at which the mode was triggered and maintain its current altitude. +The loiter radius is set by the parameter [NAV_LOITER_RAD](#NAV_LOITER_RAD). +Note that if the vehicle altitude is below [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT), it will ascend to that minimum altitude before circling. -### 매개변수 +The default loiter mode is entered when you switch to Hold mode without explicitly specifying any loiter behaviour. +For example, if you switch to Hold mode using an RC switch, select **Hold** on the QGC flight mode selector, or activate the mode using the MAVLink [MAV_CMD_DO_SET_MODE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) command. + +### Orbit Loiter Mode + + + +The aircraft travels towards a _specified_ orbit center position, then circles it with a given direction and radius. + +This behaviour can be accessed in QGroundControl by clicking on the map in Fly view, selecting **Orbit at Location**, and configuring the radius. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) command. +Note that PX4 respects the specified centre point (`param5`, `param6`, `param7`), and the radius and direction (`param1`). +PX4 ignores `param3` (Yaw behaviour) and `param4` (Orbits). +The value of `param2` (velocity) is also ignored, but the speed can be controlled using the [MAV_CMD_DO_CHANGE_SPEED](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) command (constrained between `FW_AIRSPD_MAX` and `FW_AIRSPD_MIN`). +PX4 outputs orbit status using the [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) message. + +### Figure 8 Loiter Mode + + + +The aircraft flys towards the closest point on a specified figure 8 path and then follows it. +The path is defined by the figure 8 centre position, orientation, and radius of two circles. + +The feature is experimental, and is not present in PX4 firmware by default (on most flight controller boards). +It can be included by setting the `CONFIG_FIGURE_OF_EIGHT` key in the [PX4 board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) for your board and rebuilding. +For example, this is enabled on the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/auterion/fmu-v6s/default.px4board#L46) file for the `auterion/fmu-v6s` board. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) command (PX4 respects all the parameters). +PX4 outputs the figure 8 status using the [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) message. + +:::info +Figure 8 loitering is not currently supported by QGC: [QGC#12778: Need Support Figure of eight (8 figure) loitering by QGC](https://github.com/mavlink/qgroundcontrol/issues/12778). +::: + +Figure 8 loitering is also available in the simulator. +You can test it in [Gazebo](../sim_gazebo_gz/index.md) using a fixed wing frame: + +```sh +make px4_sitl gz_rc_cessna +``` + +## 매개변수 Hold mode behaviour can be configured using the parameters below. | 매개변수 | 설명 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | | [NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | Minimum height for loiter mode (vehicle will ascend to this altitude if mode is engaged at a lower altitude). | +## MAVLink Commands + +The following commands are relevant to this mode: + +- [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) - Switch to Hold mode and start the specified [Orbit loiter](#orbit-loiter-mode). + Params 2 (velocity), 3 (yaw), 4 (orbits) are ignored. + [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) is emitted. +- [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) - Switch to Hold mode and start the specified [Figure 8 loiter](#figure-8-loiter-mode). + All params are respected. + [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) is emitted. + +Note, other commands may be supported. + ## See Also -[Hold Mode (MC)](../flight_modes_mc/hold.md) +- [Hold Mode (MC)](../flight_modes_mc/hold.md) diff --git a/docs/ko/flight_modes_fw/takeoff.md b/docs/ko/flight_modes_fw/takeoff.md index a9280230b2..7cce984ec9 100644 --- a/docs/ko/flight_modes_fw/takeoff.md +++ b/docs/ko/flight_modes_fw/takeoff.md @@ -49,8 +49,8 @@ If the local position is invalid or becomes invalid while executing the takeoff, ::: info -- Takeoff towards a target position was added in . -- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . +- Takeoff towards a target position was added in . +- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . - QGroundControl does not support `MAV_CMD_NAV_TAKEOFF` (at time of writing). ::: diff --git a/docs/ko/gps_compass/rtk_gps.md b/docs/ko/gps_compass/rtk_gps.md index 4f2c78ef57..07270685a5 100644 --- a/docs/ko/gps_compass/rtk_gps.md +++ b/docs/ko/gps_compass/rtk_gps.md @@ -21,52 +21,59 @@ PX4 supports the [u-blox M8P](https://www.u-blox.com/en/product/neo-m8p), [u-blo The table indicates devices that also output yaw, and that can provide yaw when two on-vehicle units are used. It also highlights devices that connect via the CAN bus, and those which support PPK (Post-Processing Kinematic). -| 장치 | GPS | 나침반 | [DroneCAN](../dronecan/index.md) | [GPS Yaw](#configuring-gps-as-yaw-heading-source) | PPK | -| :------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------: | :------: | :------------------------------: | :-----------------------------------------------: | :-: | -| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | -| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna][SeptDualAnt] | | -| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | BMP390 | ✓ | | | -| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | -| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | -| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | -| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | -| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P](https://docs.datagnss.com/gnss/gnss_module/D10P_RTK) | IST8310 | | ✘ | | -| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | -| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | -| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | -| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | -| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | -| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna][UnicoreDualAnt] | | -| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | -| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | -| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | -| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | -| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | -| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | +| 장치 | GPS | 나침반 | [DroneCAN] | [GPS Yaw] | PPK | +| :------------------------------------------------------------------------------------------------------------------- | :------------------: | :------: | :--------: | :---------------------------------: | :-: | +| [ARK G5 RTK GPS](../dronecan/ark_g5_rtk_gps.md) | [mosaic-G5 P3] | IIS2MDC | ✓ | | | +| [ARK G5 RTK HEADING GPS](../dronecan/ark_g5_rtk_heading_gps.md) | [mosaic-G5 P3H] | IIS2MDC | ✓ | [Heading Capability][mosaic-G5 P3H] | | +| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | +| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna] | | +| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | IIS2MDC | ✓ | | | +| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | +| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P] | | +| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P] | | +| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | +| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | +| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | +| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P] | | +| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P] | IST8310 | | ✘ | | +| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | +| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | +| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | +| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P] | | +| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P] | | +| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | +| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P] | | +| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | +| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna] | | +| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | +| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | +| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P] | | +| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | +| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | +| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | +| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P] | | +| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P] | | +| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | [RaccnLabL1L2ZED-F9P ext_ant]: https://docs.raccoonlab.co/guide/gps_mag_baro/gnss_external_antenna_f9p_v320.html [RaccoonLab L1/L2 ZED-F9P]: https://docs.raccoonlab.co/guide/gps_mag_baro/gps_l1_l2_zed_f9p.html -[DualF9P]: ../gps_compass/u-blox_f9p_heading.md -[SeptDualAnt]: ../gps_compass/septentrio.md#gnss-based-heading -[UnicoreDualAnt]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw +[Dual F9P]: ../gps_compass/u-blox_f9p_heading.md +[Septentrio Dual Antenna]: ../gps_compass/septentrio.md#gnss-based-heading +[Unicore Dual Antenna]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw [DATAGNSS GEM1305 RTK]: ../gps_compass/rtk_gps_gem1305.md +[DroneCAN]: ../dronecan/index.md +[GPS Yaw]: #configuring-gps-as-yaw-heading-source +[mosaic-G5 P3]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3 +[mosaic-G5 P3H]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H +[D10P]: https://docs.datagnss.com/gnss/gnss_module/D10P_RTK 참고: @@ -146,6 +153,7 @@ RTK GPS 연결은 기본적으로 플러그앤플레이입니다. ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) 4. Survey-in이 완료되면 : + - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) diff --git a/docs/ko/middleware/uxrce_dds.md b/docs/ko/middleware/uxrce_dds.md index 4609549b66..e39ed4930b 100644 --- a/docs/ko/middleware/uxrce_dds.md +++ b/docs/ko/middleware/uxrce_dds.md @@ -332,9 +332,11 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable. The uXRCE-DDS client module can synchronize the timestamp of the messages exchanged over the bridge. This is the default configuration. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled. - - [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX): Index-based namespace definition + - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. :::info Many ports are already have a default configuration. @@ -439,7 +441,7 @@ will generate topics under the namespaces: ::: -- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. diff --git a/docs/ko/neural_networks/index.md b/docs/ko/neural_networks/index.md new file mode 100644 index 0000000000..016a8cbe0e --- /dev/null +++ b/docs/ko/neural_networks/index.md @@ -0,0 +1,21 @@ +# Neural Network Control + +PX4 supports the following mechanisms for using neural networks for multirotor control: + +- [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) — A generic neural network module that you can modify to use different underlying neural network and training models and compile into the firmware. +- [RAPTOR: A Neural Network Module for Adaptive Quadrotor Control](../neural_networks/raptor.md) — An adaptive RL NN module that works well with different Quad configurations without additional training. + +Generally you will select the former if you wish to experiment with custom neural network architectures and train them using PyTorch or TensorFlow, and the latter if you want to use a pre-trained neural-network controller that works out-of-the-box (without training for your particular platform) or if you train your own policies using [RLtools](https://rl.tools). + +Note that both modules are experimental and provided for experimentation. +The table below provides more detail on the differences. + +| Use Case | [`mc_raptor`](../neural_networks/raptor.md) | [`mc_nn_control`](../neural_networks/mc_neural_network_control.md) | +| ---------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ | +| Pre-trained policy that adapts to any quadrotor without training | ✓ RAPTOR | ✘ | +| Train policy in PyTorch/TF | ✘ | ✓ TF Lite | +| Train policy in RLtools | ✓ | ✘ | +| Use manual control (remote) with NN policy | ✘ GPS/MoCap | ✓ Manual attitude commands | +| Load policy checkpoints from SD card | ✓ Upload via MAVLink FTP | ✘ Compiled into firmware | +| Offboard setpoints | ✓ MAVLink | ✘ | +| Internal Trajectory Generator | ✓ (Position, Lissajous) | ✘ | diff --git a/docs/ko/neural_networks/mc_neural_network_control.md b/docs/ko/neural_networks/mc_neural_network_control.md new file mode 100644 index 0000000000..172bc3a1ce --- /dev/null +++ b/docs/ko/neural_networks/mc_neural_network_control.md @@ -0,0 +1,119 @@ +# MC Neural Networks Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. +It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. + +The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](./tflm.md) module. +The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. +While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. +Note that after training the network you will need to update and rebuild PX4. + +TLFM is a mature inference library intended for use on embedded devices. +It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. +If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). + +This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. +The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. + +If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). + +## Neural Network PX4 Firmware + +:::warning +This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). +::: + +The module has been tested on a number of configurations, which can be build locally using the commands: + +```sh +make px4_sitl_neural +``` + +```sh +make px4_fmu-v6c_neural +``` + +```sh +make mro_pixracerpro_neural +``` + +You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: + +```sh +CONFIG_LIB_TFLM=y +CONFIG_MODULES_MC_NN_CONTROL=y +``` + +:::tip +The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. +::: + +## Example Module Overview + +The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: + +![neural_control](../../assets/advanced/neural_control.png) + +In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. +We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. +We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) + +### Input + +The input can be changed to whatever you want. +Set up the input you want to use during training and then provide the same input in PX4. +In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: + +- [3] Local position error. (goal position - current position) +- [6] The first 2 rows of a 3 dimensional rotation matrix. +- [3] Linear velocity +- [3] Angular velocity + +All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. +PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. +Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. + +![ENU-NED](../../assets/advanced/ENU-NED.png) + +ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. + +### 출력 + +The output consists of 4 values, the motor forces, one for each motor. +These are transformed in the `RescaleActions()` function. +This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. +So the output from the network needs to be normalized before they can be sent to the motors in PX4. + +The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. +The publishing is handled in `PublishOutput(float* command_actions)` function. + +:::tip +If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. +Decrease it for more thrust. +::: + +## Training your own Network + +The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). +But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. + +Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. +If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). + +You should do one system identification flight for this and get an approximate inertia matrix for your platform. +On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). + +Then do the following steps: + +- Do a hover flight +- Read of the logs what RPM is required for the drone to hover. +- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. +- Insert these values into the Aerial Gym configuration and train your network. +- Convert the network as explained in [TFLM](tflm.md). diff --git a/docs/ko/neural_networks/nn_module_utilities.md b/docs/ko/neural_networks/nn_module_utilities.md new file mode 100644 index 0000000000..5b21cb6817 --- /dev/null +++ b/docs/ko/neural_networks/nn_module_utilities.md @@ -0,0 +1,86 @@ +# Neural Network Module: System Integration + +The neural control module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) implements an end-to-end controller utilizing neural networks. + +The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](./tflm.md). +This page covers the changes that were made to integrate the module into PX4, both within the module, and in larger system configuration. + +:::tip +This topic should help you to shape the module to your own needs. + +You will need some familiarity with PX4 development. +For more information see the developer [Getting Started](../dev_setup/getting_started.md). +::: + +## 자동 실행 + +A line to autostart the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module has been added in the [`ROMFS/px4fmu_common/init.d/rc.mc_apps`](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rc.mc_apps) startup script. + +It checks whether the module is included by looking for the parameter [MC_NN_EN](../advanced_config/parameter_reference.md#MC_NN_EN). +If this is set to `1` (the default value), the module will be started when booting PX4. +Similarly you could create other parameters in the [`mc_nn_control_params.c`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/mc_nn_control_params.c) file for other startup script checks. + +## Custom Flight Mode + +The module creates its own flight mode "Neural Control" which lets you choose it from the flight mode menu in QGC and bind it to a switch on you RC controller. +This is done by using the [ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) internally. +This involves several steps and is visualized here: + +:::info +The module does not actually use ROS 2, it just uses the API exposed through uORB topics. +::: + +:::info +In some QGC versions the flight mode does not show up, so make sure to update to the newest version. +This only works for some flight controllers, so you might have to use an RC controller to switch to the correct external flight mode. +::: + +![neural_mode_registration](../../assets/advanced/neural_mode_registration.png) + +1. Publish a [RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md). + This specifies what you want to create, you can read more about this in the [Control Interface](../ros2/px4_ros2_control_interface.md). + In this case we register an arming check and a mode. +2. Wait for a [RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md). + This will give feedback on wether the mode registration was successful, and what the mode and arming check id is for the new mode. +3. [Optional] With the mode id, publish a [VehicleControlMode](../msg_docs/VehicleControlMode.md) message on the `config_control_setpoints` topic. + Here you can configure what other modules run in parallel. + The example controller replaces everything, so it turns off allocation. + If you want to replace other parts you can enable or disable the modules accordingly. +4. [Optional] With the mode id, publish a [ConfigOverrides](../msg_docs/ConfigOverrides.md) on the `config_overrides_request` topic. + (This is not done in the example module) This will let you defer failsafes or stop it from automatically disarming. +5. When the mode has been registered a [ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) will be sent, asking if your mode has everything it needs to run. + This message must be answered with a [ArmingCheckReply](../msg_docs/ArmingCheckReply.md) so the mode is not flagged as unresponsive. + In this response it is possible to set what requirements the mode needs to run, like local position. + If any of these requirements are set the commander will stop you from switching to the mode if they are not fulfilled. + It is also important to set health_component_index and num_events to 0 to not get a segmentation fault. + Unless you have a health component or events. +6. Listen to the [VehicleStatus](../msg_docs/VehicleStatus.md) topic. + If the nav_state equals the assigned `mode_id`, then the Neural Controller is activated. +7. When active the module will run the controller and publish to [ActuatorMotors](../msg_docs/ActuatorMotors.md). + If you want to replace a different part of the controller, you should find the appropriate topic to publish to. + +To see how the requests are handled you can check out [src/modules/commander/ModeManagement.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeManagement.cpp). + +## 로깅 + +To add module-specific logging a new topic has been added to [uORB](../middleware/uorb.md) called [NeuralControl](../msg_docs/NeuralControl.md). +The message definition is also added in `msg/CMakeLists.txt`, and to [`src/modules/logger/logged_topics.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/logger/logged_topics.cpp) under the debug category. +For these messages to be saved in your logs you need to include `debug` in the [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) parameter. + +## Timing + +The module has two includes for measuring the inference times. +The first one is a driver that works on the actual flight controller units, but a second one, `chrono`, is loaded for SITL testing. +Which timing library is included and used is based on wether PX4 is built with NUTTX or not. + +## Changing the setpoint + +The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message's position fields to define its target. +To follow a trajectory, you can send updated setpoints. +For an example of how to do this in a PX4 module, see the [mc_nn_testing](https://github.com/SindreMHegre/PX4-Autopilot-public/tree/main/src/modules/mc_nn_testing) module in this fork. +Note that this is not included in upstream PX4. +To use it, copy the module folder from the linked repository into your workspace, and enable it by adding the following line to your `.px4board` file: + +```sh +CONFIG_MODULES_MC_NN_TESTING=y +``` diff --git a/docs/ko/neural_networks/raptor.md b/docs/ko/neural_networks/raptor.md new file mode 100644 index 0000000000..59127aa64e --- /dev/null +++ b/docs/ko/neural_networks/raptor.md @@ -0,0 +1,221 @@ +# RAPTOR: A Neural Network Module for Adaptive Quadrotor Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +RAPTOR is a tiny reinforcement-learning based neural network module for quadrotor control that can be used to control a wide variety of quadrotors without retuning. + +This topic provides an overview of the fundamental concepts, and explains how you can use the module in simulation and real hardware. + +## 개요 + +![Visual Abstract](../../assets/advanced/neural_networks/raptor/visual_abstract.jpg) + +RAPTOR is an adaptive policy for end-to-end quadrotor control. +It is motivated by the human ability to adapt learned behaviours to similar situations. +For example, while humans may initially require many hours of driving experience to be able to smoothly control the car and blend into traffic, when faced with a new vehicle they do not need to re-learn how to drive — they only need to experience a few rough braking/acceleration/steering responses to adjust their previously learned behavior. + +Reinforcement Learning (RL) is a machine learning technique that uses trial and error to learn decision making/control behaviors, which is similar to the way that humans learn to drive. +RL is interesting for controlling robots (and particularly UAVs) because it overcomes some fundamental limitations of classic, modular control architectures (information loss at module boundaries, requirement for expert tuning, etc). +RL has been very successful in [high-performance quadrotor flight](https://doi.org/10.1038/s41586-023-06419-4), but previous designs have not been particularly adaptable to new frames and vehicle types. + +RAPTOR fills this gap and demonstrates a single, tiny neural-network control policy that can control a wide variety of quadrotors (tested on real quadrotors from 32 g to 2.4 kg). + +For more details please refer to this video: + + + +The method we developed for training the RAPTOR policy is called Meta-Imitation Learning: + +![Diagram showing the Method Overview](../../assets/advanced/neural_networks/raptor/method.jpg) + +You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: + + + +For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). + +## 구조 + +The RAPTOR control policy is an end-to-end policy that takes position, orientation, linear velocity and angular velocity as inputs and outputs motor commands (`actuator_motors`). +To integrate it into PX4 we use the external mode registration facilities in PX4 (which also works well for internal modes as demonstrated in `mc_nn_control`). +Because of this architecture the `mc_raptor` module is completely decoupled from all other PX4 logic. + +By default, the RAPTOR module expects setpoints via `trajectory_setpoint` messages. +If no `trajectory_setpoint` messages are received or if no `trajectory_setpoint` is received within 200 ms, the current position and orientation (with zero velocity) is used as the setpoint. +Since feeding setpoints reliably via telemetry is still a challenge, we also implement a simple option to generate internal reference trajectories (controlled through the `MC_RAPTOR_INTREF` parameter) for demonstration and benchmarking purposes. + +## 특징 + +- Tiny neural network (just 2084 parameters) => minimal CPU usage +- Easily maintainable + - Simple CMake setup + - Self-contained (no interference with other modules) + - Single, simple and well-maintained dependency (RLtools) +- Loading neural network parameters from SD card + - Minimal flash usage (for possible inclusion into default build configurations) + - Easy development: Train new neural network and just upload it via MAVLink FTP without requiring to re-flash the firmware +- Tested on 10+ different real platforms (including flexible frames, brushed motors) +- Actively developed and maintained + +## 사용법 + +### SITL + +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate + +```sh +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 # Enable the mc_raptor module +param save +``` + +Upload the RAPTOR checkpoint to the "SD card": Separate terminal + +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` + +Restart (Ctrl+C) + +```sh +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```sh +commander mode ext{RAPTOR_MODE_ID} +``` + +#### Internal Reference Trajectory Generation + +In our experience, feeding the `trajectory_setpoint` via MAVLink (even via WiFi telemetry) is unreliable. +But we do not want to constrain this module to only platforms that have a companion board. + +For this reason we have integrated a simple internal reference trajectory generator for testing and benchmarking purposes. +It supports position (constant position and yaw setpoint) as well as configurable [Lissajous trajectories](https://en.wikipedia.org/wiki/Lissajous_curve). + +The Lissajous generator can, for example, generate smooth figure-eight trajectories that contain interesting accelerations for benchmarking and testing purposes. +Please refer to the embedded configurator later in this section to explore the Lissajous parameters and view the resulting trajectories. + +To use the internal reference generator, select the mode: `0`: Off/activation position tracking, `1`: Lissajous + +```sh +param set MC_RAPTOR_INTREF 1 +``` + +Restart (ctrl+c) + +```sh +commander takeoff +commander mode ext{RAPTOR_MODE_ID} +mc_raptor intref lissajous 0.5 1 0 2 1 1 10 3 +``` + +The trajectory is relative to the position and yaw of the vehicle at the point where the RAPTOR mode is activated (or the position and yaw where the parameters are changed if it is already activated). + +You can adjust the parameters of the trajectory with the following tool. +Make sure to copy the generated CLI string at the end: + + + +### Real-World + +#### 설정 + +The `mc_raptor` module has been mostly tested with the Holybro X500 V2 but it should also work out-of-the-box with other platforms (see the [Other Platforms](#other-platforms) section). + +```sh +make px4_fmu-v6c_raptor upload +``` + +We recommend initially testing the RAPTOR mode using a dead man's switch. +For this we configure the mode selection to be connected to a push button or a switch with a spring that automatically switches back. +In the default position we configure e.g. `Stabilized Mode` and in the pressed configuration we select `External Mode 1` (since the name of the external mode is only transmitted at runtime). +This allows to take off manually and then just trigger the RAPTOR mode for a split-second to see how it behaves. +In our experiments it has been exceptionally stable (zero crashes) but we still think progressively activating it for longer is the safest way to build confidence. + +:::warning +Make sure that your platform uses the standard PX4 quadrotor motor layout: + +1: front-right, 2: back-left, 3: front-left, 4: back-right +::: + +##### Other Platforms + +To enable the `mc_raptor` module in other platforms, just add `CONFIG_MODULES_MC_RAPTOR=y` and `CONFIG_LIB_RL_TOOLS=y` + +```diff ++++ b/boards/px4/fmu-v6c/raptor.px4board +@@ -35,2 +35,3 @@ + CONFIG_DRIVERS_UAVCAN=y ++CONFIG_LIB_RL_TOOLS=y + CONFIG_MODULES_AIRSPEED_SELECTOR=y +@@ -64,2 +65,3 @@ + CONFIG_MODULES_MC_POS_CONTROL=y ++CONFIG_MODULES_MC_RAPTOR=y + CONFIG_MODULES_MC_RATE_CONTROL=y +``` + +#### Results + +Even though there were moderate winds (~ 5 m/s) during the test, we found good figure-eight tracking performance at velocities up to 12 m/s: + +![Lissajous](../../assets/advanced/neural_networks/raptor/results_figure_eight.svg) + +We also tested the linear velocity in a straight line and found that the RAPTOR policy can reliably fly at > 17 m/s (the wind direction was orthogonal to the line): + +![Linear Oscillation](../../assets/advanced/neural_networks/raptor/results_line.svg) + +### 문제 해결 + +#### 로깅 + +Use this logging configuration to log all relevant topics at maximum rate: + +```sh +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` + +Use mavproxy FTP to upload it: + +```sh +mavproxy.py +``` + +##### Real + +```sh +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +##### SITL + +```sh +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/docs/ko/neural_networks/tflm.md b/docs/ko/neural_networks/tflm.md new file mode 100644 index 0000000000..d6d0d7ef1f --- /dev/null +++ b/docs/ko/neural_networks/tflm.md @@ -0,0 +1,77 @@ +# TensorFlow Lite Micro (TFLM) + +The PX4 [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. + +This is a mature inference library intended for use on embedded devices, and is hence a suitable choice for PX4. + +This guide explains how the TFLM library is integrated into the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module, and the changes you would have to make to use it for your own neural network. + +:::tip +For more information, see the [TFLM guide](https://ai.google.dev/edge/litert/microcontrollers/get_started). +::: + +## TLMF NN Formats + +TFLM uses networks in its own [tflite format](https://ai.google.dev/edge/litert/models/convert). +However, since many microcontrollers do not have native filesystem support, a tflite file can be converted to a C++ source and header file. + +This is what is done in `mc_nn_control`. +The tflight neural network is represented in code by the files [`control_net.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.cpp) and [`control_net.hpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.hpp). + +### Getting a Network in tflite Format + +There are many online resource for generating networks in the `.tflite` format. + +For this example we trained the network in the open source [Aerial Gym Simulator](https://ntnu-arl.github.io/aerial_gym_simulator/). +Aerial Gym includes a guide, and supports RL both for control and vision-based navigation tasks. + +The project includes conversion code for `PyTorch -> TFLM` in the [resources/conversion](https://github.com/ntnu-arl/aerial_gym_simulator/tree/main/resources/conversion) folder. + +### Updating `mc_nn_control` with your own NN + +You can convert a `.tflite` network into a `.cc` file in the ubuntu terminal with this command: + +```sh +xxd -i converted_model.tflite > model_data.cc +``` + +You will then have to modify the `control_net.hpp` and `control_net.cpp` to include the data from `model_data.cc`: + +- Take the size of the network in the bottom of the `.cc` file and replace the size in `control_net.hpp`. +- Take the data in the model array in the `cc` file, and replace the ones in `control_net.cpp`. + +You are now ready to run your own network. + +## Code Explanation + +This section explains the code used to integrate the NN in `control_net.cpp`. + +### Operations and Resolver + +Firstly we need to create the resolver and load the needed operators to run inference on the NN. +This is done in the top of `mc_nn_control.cpp`. +The number in `MicroMutableOpResolver<3>` represents how many operations you need to run the inference. + +A full list of the operators can be found in the [micro_mutable_op_resolver.h](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/micro_mutable_op_resolver.h) file. +There are quite a few supported operators, but you will not find the most advanced ones. +In the control example the network is fully connected so we use `AddFullyConnected()`. +Then the activation function is ReLU, and we `AddAdd()` for the bias on each neuron. + +### Interpreter + +In the `InitializeNetwork()` we start by setting up the model that we loaded from the source and header file. +Next is to set up the interpreter, this code is taken from the TFLM documentation and is thoroughly explained there. +The end state is that the `_control_interpreter` is set up to later run inference with the `Invoke()` member function. +The `_input_tensor` is also defined, it is fetched from `_control_interpreter->input(0)`. + +### 입력 + +The `_input_tensor` is filled in the `PopulateInputTensor()` function. +`_input_tensor` works by accessing the `->data.f` member array and fill in the required inputs for your network. +The inputs used in the control network is covered in [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md). + +### 출력 + +For the outputs the approach is fairly similar to the inputs. +After setting the correct inputs, calling the `Invoke()` function the outputs can be found by getting `_control_interpreter->output(0)`. +And from the output tensor you get the `->data.f` array. diff --git a/docs/ko/releases/1.16.md b/docs/ko/releases/1.16.md index b91d344bc2..27124c57fb 100644 --- a/docs/ko/releases/1.16.md +++ b/docs/ko/releases/1.16.md @@ -151,6 +151,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### uXRCE-DDS / ROS2 - [PX4-Autopilot#24113](https://github.com/PX4/PX4-Autopilot/pull/24113): [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to translate PX4 messages from one definition version to another dynamically +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [ROS-based waypoint missions](../ros2/px4_ros2_waypoint_missions.md). - dds_topics: add vtol_vehicle_status ([PX4-Autopilot#24582](https://github.com/PX4/PX4-Autopilot/pull/24582)) - dds_topics: add home_position ([PX4-Autopilot#24583](https://github.com/PX4/PX4-Autopilot/pull/24583)) diff --git a/docs/ko/releases/1.17.md b/docs/ko/releases/1.17.md new file mode 100644 index 0000000000..4d757780d5 --- /dev/null +++ b/docs/ko/releases/1.17.md @@ -0,0 +1,134 @@ +# PX4-Autopilot v1.17.0 Release Notes + + + + + +
+
+

This page is on a release branch, and hence probably out of date. See the latest version.

+
+
+ +This contains changes to PX4 planned for PX4 v1.17 (since the last major release [PX v1.16](../releases/1.16.md)). + +:::warning +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in PX4 v1.17 release. +New features that are not expected to go into the v1.17 release are in [PX4-Autopilot `main` Release Notes](../releases/main.md). +::: + +## Read Before Upgrading + +TBD … + +Please continue reading for [upgrade instructions](#upgrade-guide). + +## Major Changes + +- TBD + +## Upgrade Guide + +## Other changes + +### Hardware Support + +- **[New Hardware]** boards: [MicoAir743-Lite FC](../flight_controller/micoair743-lite.md) +- **[New Hardware]** boards: [RadiolinkPIX6 FC](../flight_controller/radiolink_pix6.md) +- **[New Hardware]** boards: [AP-H743-R1 FC](../flight_controller/x-mav_ap-h743r1.md) + + + +### 제어 + + + +- [MC Neural Network Module](../advanced/neural_networkss.md) + +### Estimation + +- TBD + + + +### 시뮬레이션 + +- Overhaul rover simulation: + - Add synthetic differential rover model: [PX4-gazebo-models#107](https://github.com/PX4/PX4-gazebo-models/pull/107) + - Add synthetic mecanum rover model: [PX4-gazebo-models#113](https://github.com/PX4/PX4-gazebo-models/pull/113) + - Update synthetic ackermann rover model: [PX4-gazebo-models#117](https://github.com/PX4/PX4-gazebo-models/pull/117) + +- [Simulation-in-Hardware (SIH)](../sim_sih/index.md#compatibility) + - New simulation: MC Hexacopter X + - New simulation: Ackermann Rover + +### Debug & Logging + +- TBD + +### Ethernet + +- TBD + +### uXRCE-DDS / Zenoh / ROS2 + +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [Fixed Wing lateral/longitudinal setpoint](../ros2/px4_ros2_control_interface.md#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype) (`FwLateralLongitudinalSetpointType`) and [VTOL transitions](../ros2/px4_ros2_control_interface.md#controlling-a-vtol). ([PX4-Autopilot#24056](https://github.com/PX4/PX4-Autopilot/pull/24056)). +- [UXRCE_DDS: Simple index based namespace (UXRCE_DDS_NS_IDX)](../middleware/uxrce_dds.md#customizing-the-namespace) +- [Zenoh (PX4 ROS 2 rmw_zenoh)](../middleware/zenoh.md) + +### MAVLink + +- TBD + + + +### 수직이착륙기(VTOL) + +- TBD + +### Fixed-wing + +- [Fixed Wing Takeoff mode](../flight_modes_fw/takeoff.md) will now keep climbing with level wings on position loss. + A target takeoff waypoint can be set to control takeoff course and loiter altitude. ([PX4-Autopilot#25083](https://github.com/PX4/PX4-Autopilot/pull/25083)). +- Automatically suppress angular rate oscillations using [Gain compression](../features_fw/gain_compression.md). ([PX4-Autopilot#25840: FW rate control: add gain compression algorithm](https://github.com/PX4/PX4-Autopilot/pull/25840)) + +### 탐사선 + +- Removed deprecated rover module ([PX4-Autopilot#25054](https://github.com/PX4/PX4-Autopilot/pull/25054)). +- Add support for [Apps & API](../flight_modes_rover/api.md) including [Rover Setpoints](../ros2/px4_ros2_control_interface.md#rover-setpoints) ([PX4-Autopilot#25074](https://github.com/PX4/PX4-Autopilot/pull/25074), [PX4-ROS2-Interface-Lib#140](https://github.com/Auterion/px4-ros2-interface-lib/pull/140)). +- Update [rover simulation](../frames_rover/index.md#simulation) ([PX4-Autopilot#25644](https://github.com/PX4/PX4-Autopilot/pull/25644)) (see [Simulation](#simulation) release note for details). + +### ROS 2 + +- TBD diff --git a/docs/ko/releases/index.md b/docs/ko/releases/index.md index 7df22a6bf7..67c9428937 100644 --- a/docs/ko/releases/index.md +++ b/docs/ko/releases/index.md @@ -2,7 +2,8 @@ PX4 릴리스 노트는 각 릴리스의 변경 사항들을 설명합니다. -- [main](../releases/main.md) (changes since v1.16) +- [main](../releases/main.md) (changes planned for v1.18 or later) +- [v1.17](../releases/1.17.md) (changes planned for v1.17, since v1.16) - [v1.16](../releases/1.16.md) - [v1.15](../releases/1.15.md) - [v1.14](../releases/1.14.md) diff --git a/docs/ko/releases/main.md b/docs/ko/releases/main.md index e513b5ab5b..8ef3533c8d 100644 --- a/docs/ko/releases/main.md +++ b/docs/ko/releases/main.md @@ -16,13 +16,13 @@ const { site } = useData(); This contains changes to PX4 `main` branch since the last major release ([PX v1.16](../releases/1.16.md)). :::warning -PX4 v1.16 is in candidate-release testing, pending release. -Update these notes with features that are going to be in `main` but not the PX4 v1.16 release. +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in `main` (PX4 v1.18 or later) but not the PX4 v1.17 release. ::: ## Read Before Upgrading -TBD … +- TBD … Please continue reading for [upgrade instructions](#upgrade-guide). @@ -45,8 +45,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### 제어 - Added new flight mode(s): [Altitude Cruise (MC)](../flight_modes_mc/altitude_cruise.md), Altitude Cruise (FW). - For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. (PX4-Autopilot#25435: Add new flight mode: Altitude Cruise - ). + For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### Estimation @@ -59,19 +58,34 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### 시뮬레이션 +- TBD + + + +### Debug & Logging + +- [Asset Tracking](../debug/asset_tracking.md): Automatic tracking and logging of external device information including vendor name, firmware and hardware version, serial numbers. Currently supports DroneCAN devices. ([PX4-Autopilot#25617](https://github.com/PX4/PX4-Autopilot/pull/25617)) + ### Ethernet - TBD -### uXRCE-DDS / ROS2 +### uXRCE-DDS / Zenoh / ROS2 + +- TBD + + ### MAVLink @@ -92,16 +106,26 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Fixed-wing +- TBD + + ### 탐사선 +- TBD + + + ### ROS 2 - TBD diff --git a/docs/ko/ros2/px4_ros2_control_interface.md b/docs/ko/ros2/px4_ros2_control_interface.md index dae3ec9c0e..07c451a8a3 100644 --- a/docs/ko/ros2/px4_ros2_control_interface.md +++ b/docs/ko/ros2/px4_ros2_control_interface.md @@ -345,9 +345,9 @@ The used types also define the compatibility with different vehicle types. The following sections provide a list of supported setpoint types: - [MulticopterGotoSetpointType](#go-to-setpoint-multicoptergotosetpointtype): Smooth position and (optionally) heading control -- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics +- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics - [DirectActuatorsSetpointType](#direct-actuator-control-setpoint-directactuatorssetpointtype): Direct control of motors and flight surface servo setpoints -- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). +- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). :::tip The other setpoint types are currently experimental, and can be found in: [px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental). @@ -414,7 +414,7 @@ _goto_setpoint->update( #### Fixed-Wing Lateral and Longitudinal Setpoint (FwLateralLongitudinalSetpointType) - + :::info This setpoint type is supported for fixed-wing vehicles and for VTOLs in fixed-wing mode. @@ -556,7 +556,7 @@ If you want to control an actuator that does not control the vehicle's motion, b #### Rover Setpoints - + The rover modules use a hierarchical structure to propagate setpoints: @@ -590,7 +590,7 @@ An example for a rover specific drive mode using the `RoverSpeedAttitudeSetpoint ### Controlling a VTOL - + To control a VTOL in an external flight mode, ensure you're returning the correct setpoint type based on the current flight configuration: diff --git a/docs/ko/sim_sih/index.md b/docs/ko/sim_sih/index.md index 492fd425ce..413302da84 100644 --- a/docs/ko/sim_sih/index.md +++ b/docs/ko/sim_sih/index.md @@ -27,8 +27,8 @@ The Desktop computer is only used to display the virtual vehicle. - SIH for FW (airplane) and VTOL tailsitter are supported from PX4 v1.13. - SIH as SITL (without hardware) from PX4 v1.14. - SIH for Standard VTOL from PX4 v1.16. -- SIH for MC Hexacopter X from `main` (expected to be PX4 v1.17). -- SIH for Ackermann Rover from `main`. +- SIH for MC Hexacopter X from PX4 v1.17. +- SIH for Ackermann Rover from PX4 v1.17. ### Benefits From 1797ce4e884618cef9005a148a31b775a4870a44 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 28 Jan 2026 16:59:40 +1100 Subject: [PATCH 05/71] Fix round trip hello_sky translation (#26360) --- docs/en/modules/hello_sky.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/en/modules/hello_sky.md b/docs/en/modules/hello_sky.md index fd43f9cd97..86aa6bd6e9 100644 --- a/docs/en/modules/hello_sky.md +++ b/docs/en/modules/hello_sky.md @@ -88,13 +88,17 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too ``` :::tip + The main function must be named `_main` and exported from the module as shown. + ::: :::tip + `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + ::: 1. Create and open a new _cmake_ definition file named **CMakeLists.txt**. @@ -160,7 +164,7 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too 1. Create and open a new _Kconfig_ definition file named **Kconfig** and define your symbol for naming (see [Kconfig naming convention](../hardware/porting_guide_config.md#px4-kconfig-symbol-naming-convention)). Copy in the text below: - ``` + ```text menuconfig EXAMPLES_PX4_SIMPLE_APP bool "px4_simple_app" default n From 684ba28fbf6f7462559620e410b0d9b6d87162f6 Mon Sep 17 00:00:00 2001 From: Jonas Eschmann Date: Tue, 27 Jan 2026 22:54:35 -0800 Subject: [PATCH 06/71] Update iframe source to fix mixed content warning (#26309) --- docs/en/neural_networks/raptor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/neural_networks/raptor.md b/docs/en/neural_networks/raptor.md index 3867908fd8..c82b78ad6c 100644 --- a/docs/en/neural_networks/raptor.md +++ b/docs/en/neural_networks/raptor.md @@ -35,7 +35,7 @@ The method we developed for training the RAPTOR policy is called Meta-Imitation You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: - + For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). From bd6b0699cc40f53fd453dc69baf85df8b97baee5 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Tue, 27 Jan 2026 10:17:18 +1300 Subject: [PATCH 07/71] Fetch metadata files from master not main For flash constrained builds, the component metadata files are downloaded directly from s3. For the main branch, these files are currently still uploaded to master. Therefore, we also need to reference master and not main. This fixes the actuators tab in QQC for KakuteH743-Wing which is one of the boards that did not exist in source when we briefly uploaded to main before reverting back to master, presumably for QGC compatibility. --- src/lib/version/px_update_git_header.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/version/px_update_git_header.py b/src/lib/version/px_update_git_header.py index 024563b598..4b9b06d252 100755 --- a/src/lib/version/px_update_git_header.py +++ b/src/lib/version/px_update_git_header.py @@ -97,9 +97,10 @@ except: if tag_or_branch is None: # replace / so it can be used as directory name tag_or_branch = git_branch_name.replace('/', '-') - # either a release or main branch (used for metadata) + # either a release or master branch (used for metadata) + # CI uploads to 'master/' on S3 for legacy QGC compatibility if not tag_or_branch.startswith('release-'): - tag_or_branch = 'main' + tag_or_branch = 'master' header += f""" #define PX4_GIT_VERSION_STR "{git_version}" @@ -109,7 +110,7 @@ header += f""" #define PX4_GIT_OEM_VERSION_STR "{oem_tag}" -#define PX4_GIT_TAG_OR_BRANCH_NAME "{tag_or_branch}" // special variable: git tag, release or main branch +#define PX4_GIT_TAG_OR_BRANCH_NAME "{tag_or_branch}" // special variable: git tag, release or master branch """ From b7d9876cd989dc24b391c090b149e63e4cf77109 Mon Sep 17 00:00:00 2001 From: Loic Fernau <115560580+NXPLoic@users.noreply.github.com> Date: Wed, 28 Jan 2026 17:36:21 +0100 Subject: [PATCH 08/71] Added missing Defaults to VEHICLE_CMD_DO_SET_MODE (#26291) * Added missing Defaults to VEHICLE_CMD_DO_SET_MODE * Made Format --- src/modules/commander/Commander.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/modules/commander/Commander.cpp b/src/modules/commander/Commander.cpp index a35f03e933..ead99ad3d6 100644 --- a/src/modules/commander/Commander.cpp +++ b/src/modules/commander/Commander.cpp @@ -917,6 +917,12 @@ Commander::handle_command(const vehicle_command_s &cmd) } else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_OFFBOARD) { desired_nav_state = vehicle_status_s::NAVIGATION_STATE_OFFBOARD; + + } else { + main_ret = TRANSITION_DENIED; + mavlink_log_critical(&_mavlink_log_pub, "Unsupported main mode\t"); + events::send(events::ID("commander_unsupported_main_mode"), events::Log::Error, + "Unsupported main mode"); } } else { @@ -934,6 +940,12 @@ Commander::handle_command(const vehicle_command_s &cmd) } else { desired_nav_state = vehicle_status_s::NAVIGATION_STATE_MANUAL; } + + } else { + main_ret = TRANSITION_DENIED; + mavlink_log_critical(&_mavlink_log_pub, "Unsupported base mode\t"); + events::send(events::ID("commander_unsupported_base_mode"), events::Log::Error, + "Unsupported base mode"); } } From 09d3f05bcd665b2d5fc745fab68755c9a1223b16 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Thu, 29 Jan 2026 06:05:55 +1300 Subject: [PATCH 09/71] gazebo-classic: update for CI test fixes (#26335) The fix: https://github.com/PX4/PX4-SITL_gazebo-classic/pull/1084 seems to help with test failures locally. --- Tools/simulation/gazebo-classic/sitl_gazebo-classic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/simulation/gazebo-classic/sitl_gazebo-classic b/Tools/simulation/gazebo-classic/sitl_gazebo-classic index ac718b6fb2..5b6966ed57 160000 --- a/Tools/simulation/gazebo-classic/sitl_gazebo-classic +++ b/Tools/simulation/gazebo-classic/sitl_gazebo-classic @@ -1 +1 @@ -Subproject commit ac718b6fb2d6b337248e23702e75d6d1e2125054 +Subproject commit 5b6966ed572a02e8273f446acb504a45a841ca53 From f5c5f2ed8ca3fcc019cfe0cfaff868b6847ab87f Mon Sep 17 00:00:00 2001 From: Claudio Chies <61051109+Claudio-Chies@users.noreply.github.com> Date: Thu, 29 Jan 2026 02:48:30 +0100 Subject: [PATCH 10/71] Update FLARM link to the correct product page (#26361) * Update FLARM link to the correct product page * Update docs/en/peripherals/adsb_flarm.md --------- Co-authored-by: Hamish Willee --- docs/en/peripherals/adsb_flarm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/peripherals/adsb_flarm.md b/docs/en/peripherals/adsb_flarm.md index 000150418c..802f197e82 100644 --- a/docs/en/peripherals/adsb_flarm.md +++ b/docs/en/peripherals/adsb_flarm.md @@ -11,7 +11,7 @@ PX4 traffic avoidance works with ADS-B or FLARM products that supply transponder It has been tested with the following devices: - [PingRX ADS-B Receiver](https://uavionix.com/product/pingrx-pro/) (uAvionix) -- [FLARM](https://flarm.com/products/uav/atom-uav-flarm-for-drones/) +- [FLARM](https://www.flarm.com/en/drones/) ## Hardware Setup From adf1bab518891659848969116cb8939fc6ef1d10 Mon Sep 17 00:00:00 2001 From: Sindre Meyer Hegre <112490560+SindreMHegre@users.noreply.github.com> Date: Thu, 29 Jan 2026 03:10:21 +0100 Subject: [PATCH 11/71] docs: add link to masther thesis for mc_nn_control (#26279) --- docs/en/neural_networks/mc_neural_network_control.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/en/neural_networks/mc_neural_network_control.md b/docs/en/neural_networks/mc_neural_network_control.md index 6f83a67cb3..0c1cc83b57 100644 --- a/docs/en/neural_networks/mc_neural_network_control.md +++ b/docs/en/neural_networks/mc_neural_network_control.md @@ -22,7 +22,11 @@ If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tu This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). +::: tip +For more information, see the Masters thesis from which this module was created: [Deep Reinforcement Learning for Embedded Control Policies for Aerial Vehicles](https://nva.sikt.no/registration/019b26689144-efeebae8-84d6-4413-ad7f-9aceb4ff7374). + +In addition, the (Norwegian) website [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/) has a youtube video and a workshop paper . +::: ## Neural Network PX4 Firmware From 4c184f309cfa7ba9e9cd42463d1f9b5f88b02cc9 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 29 Jan 2026 13:43:22 +1100 Subject: [PATCH 12/71] docs: Max code line length 140 chars (#26368) --- docs/en/contribute/code.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/contribute/code.md b/docs/en/contribute/code.md index 529aea3bde..0d51f2f120 100644 --- a/docs/en/contribute/code.md +++ b/docs/en/contribute/code.md @@ -34,7 +34,7 @@ If you update an existing file you are not required to make the whole file compl ### Line Length -- Maximum line length is 120 characters. +- Maximum line length is 140 characters. ### File Extensions From e0f10226819969d7671586faf9ed87fa7d803841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Tue, 27 Jan 2026 11:01:01 +0100 Subject: [PATCH 13/71] ci: ignore python packages in px4-ros2-interface-lib Due to build issues with very old ROS version --- .github/workflows/ros_integration_tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ros_integration_tests.yml b/.github/workflows/ros_integration_tests.yml index 022b46fb10..bbcce560d8 100644 --- a/.github/workflows/ros_integration_tests.yml +++ b/.github/workflows/ros_integration_tests.yml @@ -90,6 +90,9 @@ jobs: mkdir -p /opt/px4_ws/src cd /opt/px4_ws/src git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib.git + # Ignore python packages due to compilation issue (can be enabled when updating ROS) + touch px4-ros2-interface-lib/px4_ros2_py/COLCON_IGNORE || true + touch px4-ros2-interface-lib/examples/python/COLCON_IGNORE || true cd .. # Copy messages to ROS workspace "${PX4_DIR}/Tools/copy_to_ros_ws.sh" "$(pwd)" From b9bd8201863824e63830bfbec53f61184c910b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Tue, 27 Jan 2026 11:01:33 +0100 Subject: [PATCH 14/71] docs: mention python bindings in ros lib --- docs/en/ros2/px4_ros2_control_interface.md | 8 +++++++- docs/en/ros2/px4_ros2_interface_lib.md | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/en/ros2/px4_ros2_control_interface.md b/docs/en/ros2/px4_ros2_control_interface.md index 81f5943882..b07a061ee9 100644 --- a/docs/en/ros2/px4_ros2_control_interface.md +++ b/docs/en/ros2/px4_ros2_control_interface.md @@ -13,7 +13,7 @@ At the time of writing, parts of the PX4 ROS 2 Control Interface are experimenta ::: -The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library that simplifies controlling PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library (with Python bindings) that simplifies controlling PX4 from ROS 2. Developers use the library to create and dynamically register modes written using ROS 2. These modes are dynamically registered with PX4, and appear to be part of PX4 to a ground station or other external system. @@ -25,6 +25,12 @@ These classes abstract the internal setpoints used by PX4, and that can therefor PX4 ROS 2 modes are easier to implement and maintain than PX4 internal modes, and provide more resources for developers in terms of processing power and pre-existing libraries. Unless the mode is safety-critical, requires strict timing or very high update rates, or your vehicle doesn't have a companion computer, you should [consider using PX4 ROS 2 modes in preference to PX4 internal modes](../concept/flight_modes.md#internal-vs-external-modes). +::: tip +If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). +Not all classes have Python bindings yet — the [supported bindings are here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_py/src/px4_ros2). +You are welcome to add and contribute missing classes. +::: + ## Overview This diagram provides a conceptual overview of how the control interface modes and mode executors interact with PX4. diff --git a/docs/en/ros2/px4_ros2_interface_lib.md b/docs/en/ros2/px4_ros2_interface_lib.md index 818db7a581..d695ab7f21 100644 --- a/docs/en/ros2/px4_ros2_interface_lib.md +++ b/docs/en/ros2/px4_ros2_interface_lib.md @@ -6,7 +6,7 @@ At the time of writing, parts of the PX4 ROS 2 Interface Library are experimental, and hence subject to change. ::: -The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library that simplifies controlling and interacting with PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. The library provides three high-level interfaces for developers: From 744548e9f2be6b8b2bfd2773018b65465b0e685d Mon Sep 17 00:00:00 2001 From: Phil-Engljaehringer Date: Thu, 29 Jan 2026 13:15:01 +0100 Subject: [PATCH 15/71] fix: use correct address passed with -a flag --- src/lib/drivers/mcp_common/MCP.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/drivers/mcp_common/MCP.cpp b/src/lib/drivers/mcp_common/MCP.cpp index 7f36ba11ec..558aa8293a 100644 --- a/src/lib/drivers/mcp_common/MCP.cpp +++ b/src/lib/drivers/mcp_common/MCP.cpp @@ -443,6 +443,7 @@ I2CSPIDriverBase *MCP230XX::instantiate(const I2CSPIDriverConfig &config, int ru MCP230XX_config_t tmp_config = *static_cast(config.custom_data); instance->mcp_config = tmp_config; instance->mcp_config.i2c_bus = config.bus; + instance->mcp_config.i2c_addr = config.i2c_address; if (OK != instance->init()) { delete instance; From 193a4478ed0e52491e4a933e91d41d468283e5d7 Mon Sep 17 00:00:00 2001 From: Phil-Engljaehringer Date: Thu, 29 Jan 2026 11:29:04 +0100 Subject: [PATCH 16/71] fix: adjusted probe function to new revision of TLA2528 (and add status function) --- src/drivers/adc/tla2528/tla2528.cpp | 24 ++++++++++++++++++------ src/drivers/adc/tla2528/tla2528.h | 1 + src/drivers/adc/tla2528/tla2528_main.cpp | 7 +++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/drivers/adc/tla2528/tla2528.cpp b/src/drivers/adc/tla2528/tla2528.cpp index f6f3948ef7..e537a3ca61 100644 --- a/src/drivers/adc/tla2528/tla2528.cpp +++ b/src/drivers/adc/tla2528/tla2528.cpp @@ -142,7 +142,7 @@ int TLA2528::poll_reset() uint8_t send_data[2]; uint8_t recv_data; send_data[0] = READ; - send_data[0] = GENERAL_CFG; + send_data[1] = GENERAL_CFG; int ret = transfer(&send_data[0], 2, nullptr, 0); ret |= transfer(nullptr, 0, &recv_data, 1); @@ -199,15 +199,27 @@ void TLA2528::adc_get() int TLA2528::probe() { for (int i = 0; i < 3; i++) { - // Set device in debug mode (should respond with 0xA5AX to all reads) - uint8_t send_data[3] = {SET_BIT, DATA_CFG, 0x80}; + // Select channel 0 + uint8_t send_data[3]; + send_data[0] = WRITE; + send_data[1] = CHANNEL_SEL; + send_data[2] = 0x00; // Channel 0 int ret = transfer(&send_data[0], 3, nullptr, 0); + // Put device in in manual mode + send_data[0] = WRITE; + send_data[1] = OPMODE_CFG; + send_data[2] = 0x00; + ret |= transfer(&send_data[0], 3, nullptr, 0); + + // Set device in debug mode (should respond with 0xA5AX to all reads) + send_data[0] = SET_BIT; + send_data[1] = DATA_CFG; + send_data[2] = 0x80; + ret |= transfer(&send_data[0], 3, nullptr, 0); + // Read uint8_t recv_data[2]; - send_data[0] = SET_BIT; - send_data[0] = DATA_CFG; - ret |= transfer(&send_data[0], 2, nullptr, 0); ret |= transfer(nullptr, 0, &recv_data[0], 2); // Turn debug mode off diff --git a/src/drivers/adc/tla2528/tla2528.h b/src/drivers/adc/tla2528/tla2528.h index 818d59b214..b95aaf364e 100644 --- a/src/drivers/adc/tla2528/tla2528.h +++ b/src/drivers/adc/tla2528/tla2528.h @@ -52,6 +52,7 @@ public: int init() override; void RunImpl(); int probe() override; + void print_status() override; private: static const hrt_abstime SAMPLE_INTERVAL{10_ms}; diff --git a/src/drivers/adc/tla2528/tla2528_main.cpp b/src/drivers/adc/tla2528/tla2528_main.cpp index e2463cfca3..652ac150d4 100644 --- a/src/drivers/adc/tla2528/tla2528_main.cpp +++ b/src/drivers/adc/tla2528/tla2528_main.cpp @@ -43,6 +43,13 @@ void TLA2528::print_usage() PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); } +void TLA2528::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_cycle_perf); + perf_print_counter(_comms_errors); +} + extern "C" int tla2528_main(int argc, char *argv[]) { using ThisDriver = TLA2528; From ac4f419b5021acc364fd8bdcc3f4fc16779dbefe Mon Sep 17 00:00:00 2001 From: Daniel Honies Date: Tue, 13 Jan 2026 13:23:30 +0400 Subject: [PATCH 17/71] Update 4004_gz_standard_vtol VT_F_TRANS_THR at 0.3 always triggers front transition timeout as the vehicle does not accaelerate quickly enough. With the param set to 1.0 it works. --- .../px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol b/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol index 5bd432abde..890a01f809 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol @@ -101,6 +101,6 @@ param set-default NAV_ACC_RAD 5 param set-default NAV_DLL_ACT 2 param set-default VT_FWD_THRUST_EN 4 -param set-default VT_F_TRANS_THR 0.3 +param set-default VT_F_TRANS_THR 1 param set-default VT_TYPE 2 param set-default FD_ESCS_EN 0 From 03264ce1a703b603675b59b93a1ec3d771967cfe Mon Sep 17 00:00:00 2001 From: ttechnick Date: Fri, 16 Jan 2026 11:04:27 +0100 Subject: [PATCH 18/71] failsafe: prevent switch offboard -->pos without RC --- src/modules/commander/failsafe/failsafe.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/modules/commander/failsafe/failsafe.cpp b/src/modules/commander/failsafe/failsafe.cpp index 5090b22a9c..b0c19db29b 100644 --- a/src/modules/commander/failsafe/failsafe.cpp +++ b/src/modules/commander/failsafe/failsafe.cpp @@ -669,6 +669,15 @@ FailsafeBase::Action Failsafe::checkModeFallback(const failsafe_flags_s &status_ if (action == Action::Disarm) { return action; } + + if (action == Action::FallbackPosCtrl || action == Action::FallbackAltCtrl || action == Action::FallbackStab) { + // Check if RC is available, if not use the mode specified in NAV_RCL_ACT + if (status_flags.manual_control_signal_lost) { + ActionOptions rc_loss_action = fromNavDllOrRclActParam(_param_nav_rcl_act.get()); + action = rc_loss_action.action; + } + + } } // PosCtrl/PositionSlow -> AltCtrl From 90fec17427c60f53512bd81ca16e2394e92e631e Mon Sep 17 00:00:00 2001 From: Eric Katzfey <53063038+katzfey@users.noreply.github.com> Date: Thu, 29 Jan 2026 13:02:36 -0800 Subject: [PATCH 19/71] CRSF_RC: Replace strlcpy with strncpy and null termination. strlcpy is a BSD extension and is not part of standard C/C++. (#26381) It's typically not available in glibc's . --- src/drivers/rc/crsf_rc/CrsfParser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/drivers/rc/crsf_rc/CrsfParser.cpp b/src/drivers/rc/crsf_rc/CrsfParser.cpp index 98e2a2938d..1e8b8e0d0c 100644 --- a/src/drivers/rc/crsf_rc/CrsfParser.cpp +++ b/src/drivers/rc/crsf_rc/CrsfParser.cpp @@ -264,7 +264,8 @@ static bool ProcessElrsStatus(const uint8_t *data, const uint32_t size, CrsfPack new_packet->elrs_status.packets_bad = data[2]; new_packet->elrs_status.packets_good = (data[3] << 8) | data[4]; new_packet->elrs_status.flags = data[5]; - strlcpy(new_packet->elrs_status.message, (const char *)&data[6], sizeof(new_packet->elrs_status.message)); + strncpy(new_packet->elrs_status.message, (const char *)&data[6], sizeof(new_packet->elrs_status.message) - 1); + new_packet->elrs_status.message[sizeof(new_packet->elrs_status.message) - 1] = '\0'; return true; } From e37a216393c71733c3732ac2f7f4d6af7391a1c2 Mon Sep 17 00:00:00 2001 From: Eric Katzfey <53063038+katzfey@users.noreply.github.com> Date: Thu, 29 Jan 2026 13:03:18 -0800 Subject: [PATCH 20/71] QURT/SERIAL: Undo the breaking changes from commit 17f3db9231350caf86d9f0af6591f66044d9829c. (#26382) A check was added for a non-existant parameter. This commit removes those. --- platforms/qurt/src/px4/SerialImpl.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/platforms/qurt/src/px4/SerialImpl.cpp b/platforms/qurt/src/px4/SerialImpl.cpp index c7d78baffe..ad93529f9b 100644 --- a/platforms/qurt/src/px4/SerialImpl.cpp +++ b/platforms/qurt/src/px4/SerialImpl.cpp @@ -416,12 +416,8 @@ bool SerialImpl::getSingleWireMode() const bool SerialImpl::setSingleWireMode() { - if (enable) { - PX4_ERR("Qurt platform does not support single wire mode"); - return false; - } - - return true; + PX4_ERR("Qurt platform does not support single wire mode"); + return false; } bool SerialImpl::getSwapRxTxMode() const @@ -431,12 +427,8 @@ bool SerialImpl::getSwapRxTxMode() const bool SerialImpl::setSwapRxTxMode() { - if (enable) { - PX4_ERR("Qurt platform does not support swap rx tx mode"); - return false; - } - - return true; + PX4_ERR("Qurt platform does not support swap rx tx mode"); + return false; } bool SerialImpl::setInvertedMode(bool enable) From 3075724f9e580d109fcf75c5b66e2d1bb720ba82 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Fri, 30 Jan 2026 10:19:38 +1300 Subject: [PATCH 21/71] jmavsim: update submodule (#26369) This contains: https://github.com/PX4/jMAVSim/pull/140 which updates dependencies and adds macOS arm64 support. --- Tools/simulation/jmavsim/jMAVSim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/simulation/jmavsim/jMAVSim b/Tools/simulation/jmavsim/jMAVSim index 66b764ada5..665b26d62d 160000 --- a/Tools/simulation/jmavsim/jMAVSim +++ b/Tools/simulation/jmavsim/jMAVSim @@ -1 +1 @@ -Subproject commit 66b764ada522893c05224950aa6268c809f8e48a +Subproject commit 665b26d62d36a33b6bf01c5931c589beb812c6a2 From 6be1a14e065658ca221b63155d17ca8336390afb Mon Sep 17 00:00:00 2001 From: Nick <145654544+ttechnick@users.noreply.github.com> Date: Fri, 30 Jan 2026 01:21:45 +0100 Subject: [PATCH 22/71] docs: COM_FLTT_LOW_ACT default fixed (#26374) --- docs/en/config/safety.md | 2 +- docs/ko/config/safety.md | 2 +- docs/uk/config/safety.md | 2 +- docs/zh/config/safety.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/config/safety.md b/docs/en/config/safety.md index bef0e0ea18..f97fb392aa 100644 --- a/docs/en/config/safety.md +++ b/docs/en/config/safety.md @@ -106,7 +106,7 @@ The settings and underlying parameters are shown below. | Setting | Parameter | Description | | -------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe diff --git a/docs/ko/config/safety.md b/docs/ko/config/safety.md index d84dc6633a..8c4c720942 100644 --- a/docs/ko/config/safety.md +++ b/docs/ko/config/safety.md @@ -106,7 +106,7 @@ There are several other "battery related" failsafe mechanisms that may be config | 설정 | 매개변수 | 설명 | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe diff --git a/docs/uk/config/safety.md b/docs/uk/config/safety.md index d4407a9fa4..271142256e 100644 --- a/docs/uk/config/safety.md +++ b/docs/uk/config/safety.md @@ -104,7 +104,7 @@ There are several other "battery related" failsafe mechanisms that may be config | Налаштування | Параметр | Опис | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe diff --git a/docs/zh/config/safety.md b/docs/zh/config/safety.md index 8e7ea70b1d..1253233e7b 100644 --- a/docs/zh/config/safety.md +++ b/docs/zh/config/safety.md @@ -106,7 +106,7 @@ The settings and underlying parameters are shown below. | 设置 | 参数 | 描述 | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe From f8c1e8b81f9eabdffb17082aa6ea58200ad65905 Mon Sep 17 00:00:00 2001 From: tompsontan <1153614092@qq.com> Date: Fri, 30 Jan 2026 12:38:20 +0800 Subject: [PATCH 23/71] Improve QMC5883P magnetometer stability by optimizing OSR and ODR settings. (#26350) --- src/drivers/magnetometer/qmc5883p/QMC5883P.cpp | 2 ++ src/drivers/magnetometer/qmc5883p/QMC5883P.hpp | 2 +- .../magnetometer/qmc5883p/QST_QMC5883P_registers.hpp | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp b/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp index b0d9693b19..e508e8863e 100644 --- a/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp +++ b/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp @@ -244,6 +244,8 @@ void QMC5883P::RunImpl() bool QMC5883P::Configure() { + RegisterWrite(Register::REG_29, 0x06); + // first set and clear all configured register bits for (const auto ®_cfg : _register_cfg) { RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits); diff --git a/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp b/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp index 3ad532d0fb..1663fd88f4 100644 --- a/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp +++ b/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp @@ -107,7 +107,7 @@ private: static constexpr uint8_t size_register_cfg{2}; register_config_t _register_cfg[size_register_cfg] { // Register | Set bits, Clear bits - { Register::CNTL1, CNTL1_BIT::MODE_CONTINUOUS | CNTL1_BIT::OSR1_8 | CNTL1_BIT::ODR_50HZ, CNTL1_BIT::OSR2_8}, + { Register::CNTL1, CNTL1_BIT::MODE_CONTINUOUS | CNTL1_BIT::OSR2_4 | CNTL1_BIT::ODR_200HZ, CNTL1_BIT::OSR1_8}, { Register::CNTL2, CNTL2_BIT::RNG_2G, CNTL2_BIT::SOFT_RST | CNTL2_BIT::SELF_TEST}, }; }; diff --git a/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp b/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp index 57fffa6579..ff9428d48d 100644 --- a/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp +++ b/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp @@ -79,6 +79,8 @@ enum class Register : uint8_t { CNTL2 = 0x0B, // Control Register 2 CHIP_ID = 0x00, + + REG_29 = 0x29, }; // STATUS @@ -90,11 +92,11 @@ enum STATUS_BIT : uint8_t { // CNTL1 enum CNTL1_BIT : uint8_t { // OSR2[7:6] - OSR2_8 = Bit7 | Bit6, // 00 + OSR2_4 = Bit7, // 10 // OSR1[5:4] OSR1_8 = Bit5 | Bit4, // 11 // ODR[3:2] - ODR_50HZ = Bit2, // 01 + ODR_200HZ = Bit3 | Bit2, // 11 // MODE[1:0] MODE_CONTINUOUS = Bit1 | Bit0, // 11 }; From 4e59a060a835d444baec36408fa11d1df3ce930f Mon Sep 17 00:00:00 2001 From: mahima-yoga Date: Fri, 30 Jan 2026 10:23:04 +0100 Subject: [PATCH 24/71] HomePosition: only set home position using GNSS if bit 0 in EKF2_GPS_CTRL is active If the vehicle position is not set by GNSS, then the home position should not be either. --- src/modules/commander/HomePosition.cpp | 20 ++++++++++++++++++-- src/modules/commander/HomePosition.hpp | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/modules/commander/HomePosition.cpp b/src/modules/commander/HomePosition.cpp index 3825ffe9f5..4eb0f068de 100644 --- a/src/modules/commander/HomePosition.cpp +++ b/src/modules/commander/HomePosition.cpp @@ -40,7 +40,9 @@ #include "commander_helper.h" HomePosition::HomePosition(const failsafe_flags_s &failsafe_flags): ModuleParams(nullptr), - _failsafe_flags(failsafe_flags) {} + _failsafe_flags(failsafe_flags), + _param_ekf2_gps_ctrl_handle(param_find("EKF2_GPS_CTRL")) +{} bool HomePosition::hasMovedFromCurrentHomeLocation() { @@ -299,6 +301,19 @@ void HomePosition::setHomePosValid() _valid = true; } +bool HomePosition::isGpsHorizontalFusionEnabled() +{ + // If parameter doesn't exist, allow GPS usage + if (_param_ekf2_gps_ctrl_handle == PARAM_INVALID) { + return true; + } + + // Check if bit 0 (horizontal position fusion) is set + int32_t ekf2_gps_ctrl = 0; + param_get(_param_ekf2_gps_ctrl_handle, &ekf2_gps_ctrl); + return (ekf2_gps_ctrl & 1); +} + void HomePosition::updateHomePositionYaw(float yaw) { home_position_s home = _home_position_pub.get(); @@ -348,7 +363,8 @@ void HomePosition::update(bool set_automatically, bool check_if_changed) const bool epv_valid = vehicle_gps_position.epv < kHomePositionGPSRequiredEPV; const bool evh_valid = vehicle_gps_position.s_variance_m_s < kHomePositionGPSRequiredEVH; - _gps_position_for_home_valid = time_valid && fix_valid && eph_valid && epv_valid && evh_valid; + _gps_position_for_home_valid = time_valid && fix_valid && eph_valid && epv_valid && evh_valid + && isGpsHorizontalFusionEnabled(); if (_param_com_home_en.get() && _gps_position_for_home_valid && _last_gps_timestamp != 0 && _last_baro_timestamp != 0 && _takeoff_time != 0 && now < _takeoff_time + kHomePositionCorrectionTimeWindow) { diff --git a/src/modules/commander/HomePosition.hpp b/src/modules/commander/HomePosition.hpp index dd218c902e..fd5eb1e72d 100644 --- a/src/modules/commander/HomePosition.hpp +++ b/src/modules/commander/HomePosition.hpp @@ -74,6 +74,7 @@ public: private: bool hasMovedFromCurrentHomeLocation(); + bool isGpsHorizontalFusionEnabled(); void setHomePosValid(); void updateHomePositionYaw(float yaw); @@ -113,4 +114,5 @@ private: DEFINE_PARAMETERS( (ParamBool) _param_com_home_en ) + param_t _param_ekf2_gps_ctrl_handle{PARAM_INVALID}; }; From 8d970138221a9dbd76b6950a55a2303493120002 Mon Sep 17 00:00:00 2001 From: Pernilla Date: Fri, 30 Jan 2026 10:33:02 +0100 Subject: [PATCH 25/71] Mavlink: increase stream rate of GIMBAL_DEVICE_ATTITUDE_STATUS --- src/modules/mavlink/mavlink_main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/mavlink/mavlink_main.cpp b/src/modules/mavlink/mavlink_main.cpp index 1b72a220b0..2003189297 100644 --- a/src/modules/mavlink/mavlink_main.cpp +++ b/src/modules/mavlink/mavlink_main.cpp @@ -1433,7 +1433,7 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("ESC_STATUS", 1.0f); configure_stream_local("ESTIMATOR_STATUS", 0.5f); configure_stream_local("EXTENDED_SYS_STATE", 1.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); #if defined(MAVLINK_MSG_ID_GLOBAL_POSITION) @@ -1511,7 +1511,7 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("EFI_STATUS", 2.0f); configure_stream_local("ESTIMATOR_STATUS", 1.0f); configure_stream_local("EXTENDED_SYS_STATE", 5.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("GLOBAL_POSITION_INT", 50.0f); @@ -1685,7 +1685,7 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("GPS_GLOBAL_ORIGIN", 1.0f); configure_stream_local("GPS_RAW_INT", unlimited_rate); configure_stream_local("GPS_STATUS", 1.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 0.5f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("HIGHRES_IMU", 50.0f); configure_stream_local("HOME_POSITION", 0.5f); @@ -1765,7 +1765,7 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("DISTANCE_SENSOR", 10.0f); configure_stream_local("MOUNT_ORIENTATION", 10.0f); configure_stream_local("OBSTACLE_DISTANCE", 10.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 5.0f); configure_stream_local("ESC_INFO", 1.0f); @@ -1833,7 +1833,7 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("DISTANCE_SENSOR", 1.0f); configure_stream_local("MOUNT_ORIENTATION", 2.0f); configure_stream_local("OBSTACLE_DISTANCE", 2.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 2.0f); configure_stream_local("ESC_INFO", 1.0f); From 40dc011d82f5b79c11718992200e60c8534929ca Mon Sep 17 00:00:00 2001 From: Nick <145654544+ttechnick@users.noreply.github.com> Date: Fri, 30 Jan 2026 14:09:56 +0100 Subject: [PATCH 26/71] failsafe: prevent Hold when no action is taken (#26383) --- src/modules/commander/failsafe/failsafe.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/commander/failsafe/failsafe.cpp b/src/modules/commander/failsafe/failsafe.cpp index b0c19db29b..2f5777b69d 100644 --- a/src/modules/commander/failsafe/failsafe.cpp +++ b/src/modules/commander/failsafe/failsafe.cpp @@ -422,6 +422,7 @@ FailsafeBase::ActionOptions Failsafe::fromRemainingFlightTimeLowActParam(int par switch (command_after_remaining_flight_time_low(param_value)) { case command_after_remaining_flight_time_low::None: options.action = Action::None; + options.allow_user_takeover = UserTakeoverAllowed::Never; // Execute immediately without delay break; case command_after_remaining_flight_time_low::Warning: @@ -435,6 +436,7 @@ FailsafeBase::ActionOptions Failsafe::fromRemainingFlightTimeLowActParam(int par default: options.action = Action::None; + options.allow_user_takeover = UserTakeoverAllowed::Never; break; } From 63c4f4ac3e02621ab226261f45b54c2e259743a6 Mon Sep 17 00:00:00 2001 From: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:31:38 -0900 Subject: [PATCH 27/71] uavcannode: publisher: Fix2: fix eph/epv off by sqrt bug (#26389) --- src/drivers/uavcannode/Publishers/GnssFix2.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/drivers/uavcannode/Publishers/GnssFix2.hpp b/src/drivers/uavcannode/Publishers/GnssFix2.hpp index 4f3223ec48..4f0968c269 100644 --- a/src/drivers/uavcannode/Publishers/GnssFix2.hpp +++ b/src/drivers/uavcannode/Publishers/GnssFix2.hpp @@ -113,10 +113,10 @@ public: } // Diagonal matrix - // position variances -- Xx, Yy, Zz - fix2.covariance.push_back(gps.eph); - fix2.covariance.push_back(gps.eph); - fix2.covariance.push_back(gps.epv); + // position variances -- Xx, Yy, Zz (eph/epv are std dev in meters, must square for variance) + fix2.covariance.push_back(gps.eph * gps.eph); + fix2.covariance.push_back(gps.eph * gps.eph); + fix2.covariance.push_back(gps.epv * gps.epv); // velocity variance -- Vxx, Vyy, Vzz fix2.covariance.push_back(gps.s_variance_m_s); fix2.covariance.push_back(gps.s_variance_m_s); From 390c9d6ccf596ce7dab6c176b3eddc851f9a7d85 Mon Sep 17 00:00:00 2001 From: Levi Todes <43195586+LeTo37@users.noreply.github.com> Date: Sun, 1 Feb 2026 04:57:39 +0200 Subject: [PATCH 28/71] SHT3X driver: change state timer variable from uint32 to uint64. (#24264) Prevents current behaviour of repeated entry into 'init' state and associated log spamming after +-72 minutes. Signed-off-by: LeTo37 Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> --- src/drivers/hygrometer/sht3x/sht3x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/hygrometer/sht3x/sht3x.h b/src/drivers/hygrometer/sht3x/sht3x.h index 2750b8d9ff..a01a0a4335 100644 --- a/src/drivers/hygrometer/sht3x/sht3x.h +++ b/src/drivers/hygrometer/sht3x/sht3x.h @@ -110,7 +110,7 @@ private: float measured_temperature = 0; float measured_humidity = 0; - uint32_t measurement_time = 0; + uint64_t measurement_time = 0; uint16_t measurement_index = 0; sht_info _sht_info; From d5c4ace6155368d1ee1ff5295fae51437f751248 Mon Sep 17 00:00:00 2001 From: PX4 Build Bot Date: Mon, 2 Feb 2026 08:19:19 +1100 Subject: [PATCH 29/71] New Crowdin translations - uk (#26397) Co-authored-by: Crowdin Bot --- docs/uk/SUMMARY.md | 3 + docs/uk/config_vtol/index.md | 1 + docs/uk/config_vtol/vtol_ice_shedding.md | 22 ++ docs/uk/contribute/code.md | 2 +- docs/uk/modules/hello_sky.md | 6 +- .../mc_neural_network_control.md | 6 +- docs/uk/neural_networks/raptor.md | 2 +- docs/uk/peripherals/adsb_flarm.md | 2 +- docs/uk/ros2/px4_ros2_control_interface.md | 8 +- docs/uk/ros2/px4_ros2_interface_lib.md | 2 +- docs/uk/vtx/index.md | 287 ++++++++++++++++++ 11 files changed, 334 insertions(+), 7 deletions(-) create mode 100644 docs/uk/config_vtol/vtol_ice_shedding.md create mode 100644 docs/uk/vtx/index.md diff --git a/docs/uk/SUMMARY.md b/docs/uk/SUMMARY.md index bb59e97e97..dc24c04642 100644 --- a/docs/uk/SUMMARY.md +++ b/docs/uk/SUMMARY.md @@ -93,6 +93,7 @@ - [Настройка Зворотнього Переходу](config_vtol/vtol_back_transition_tuning.md) - [ВЗІП Датчик польоту](config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](config_vtol/vtol_weathervane.md) + - [VTOL Ice Shedding](config_vtol/vtol_ice_shedding.md) - [Режим польоту](flight_modes_vtol/index.md) - [Mission Mode (VTOL)](flight_modes_vtol/mission.md) - [Return Mode (VTOL)](flight_modes_vtol/return.md) @@ -361,6 +362,8 @@ - [Супутниковий зв'язок (Iridium/RockBlock)](advanced_features/satcom_roadblock.md) + - [Analog Video Transmitters](vtx/index.md) + - [Енергетичні системи](power_systems/index.md) - [Налаштування оцінки батареї](config/battery.md) - [Battery Chemistry Overview](power_systems/battery_chemistry.md) diff --git a/docs/uk/config_vtol/index.md b/docs/uk/config_vtol/index.md index 0552c6a477..fc6d447a61 100644 --- a/docs/uk/config_vtol/index.md +++ b/docs/uk/config_vtol/index.md @@ -9,3 +9,4 @@ As part of this you should calibrate the [Airspeed sensor](../config/airspeed.md - [Back-transition Tuning](../config_vtol/vtol_back_transition_tuning.md) - [VTOL w/o Airspeed Sensor](../config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](../config_vtol/vtol_weathervane.md) +- [Ice Shedding](../config_vtol/vtol_ice_shedding.md) diff --git a/docs/uk/config_vtol/vtol_ice_shedding.md b/docs/uk/config_vtol/vtol_ice_shedding.md new file mode 100644 index 0000000000..de94fb7e37 --- /dev/null +++ b/docs/uk/config_vtol/vtol_ice_shedding.md @@ -0,0 +1,22 @@ +# VTOL Ice Shedding feature + +## Загальний огляд + +Ice shedding is a feature that periodically spins unused motors in fixed-wing +flight, to break off any ice that is starting to build up in the motors while it +is still feasible to do so. + +It is configured by the paramter `CA_ICE_PERIOD`. When it is 0, the feature is +disabled, when it is above 0, it sets the duration of the ice shedding cycle in +seconds. In each cycle, the rotors are spun for two seconds at a motor output of +0.01. + +:::warning +When enabling the feature on a new airframe, there is the risk of producing +torques that disturb the fixed-wing rate controller. To mitigate this risk: + +- Set your `PWM_MIN` values correctly, so that the motor output 0.01 actually + produces 1% thrust +- Be prepared to take control and switch back to multicopter + +::: diff --git a/docs/uk/contribute/code.md b/docs/uk/contribute/code.md index dcd001e2e0..36fa4646e4 100644 --- a/docs/uk/contribute/code.md +++ b/docs/uk/contribute/code.md @@ -34,7 +34,7 @@ Not all PX4 source code matches the style guide, but any _new code_ that you wri ### Довжина рядка -- Максимальна довжина рядка становить 120 символів. +- Maximum line length is 140 characters. ### Розширення файлів diff --git a/docs/uk/modules/hello_sky.md b/docs/uk/modules/hello_sky.md index 90dfe6b40e..6f87812019 100644 --- a/docs/uk/modules/hello_sky.md +++ b/docs/uk/modules/hello_sky.md @@ -89,15 +89,19 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too ``` :::tip + The main function must be named `_main` and exported from the module as shown. + ::: :::tip + `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + ::: 3. Create and open a new _cmake_ definition file named **CMakeLists.txt**. @@ -166,7 +170,7 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too 4. Create and open a new _Kconfig_ definition file named **Kconfig** and define your symbol for naming (see [Kconfig naming convention](../hardware/porting_guide_config.md#px4-kconfig-symbol-naming-convention)). Скопіюйте текст нижче: - ``` + ```text menuconfig EXAMPLES_PX4_SIMPLE_APP bool "px4_simple_app" default n diff --git a/docs/uk/neural_networks/mc_neural_network_control.md b/docs/uk/neural_networks/mc_neural_network_control.md index c0527480a1..53339f5ee3 100644 --- a/docs/uk/neural_networks/mc_neural_network_control.md +++ b/docs/uk/neural_networks/mc_neural_network_control.md @@ -22,7 +22,11 @@ If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tu This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). +:::tip +For more information, see the Masters thesis from which this module was created: [Deep Reinforcement Learning for Embedded Control Policies for Aerial Vehicles](https://nva.sikt.no/registration/019b26689144-efeebae8-84d6-4413-ad7f-9aceb4ff7374). + +In addition, the (Norwegian) website [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/) has a youtube video and a workshop paper . +::: ## Neural Network PX4 Firmware diff --git a/docs/uk/neural_networks/raptor.md b/docs/uk/neural_networks/raptor.md index 7c031632c7..5568790267 100644 --- a/docs/uk/neural_networks/raptor.md +++ b/docs/uk/neural_networks/raptor.md @@ -35,7 +35,7 @@ The method we developed for training the RAPTOR policy is called Meta-Imitation You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: - + For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). diff --git a/docs/uk/peripherals/adsb_flarm.md b/docs/uk/peripherals/adsb_flarm.md index 223e1f250e..5a6c9d8c01 100644 --- a/docs/uk/peripherals/adsb_flarm.md +++ b/docs/uk/peripherals/adsb_flarm.md @@ -11,7 +11,7 @@ PX4 traffic avoidance works with ADS-B or FLARM products that supply transponder Було протестовано з наступними пристроями: - [PingRX ADS-B Receiver](https://uavionix.com/product/pingrx-pro/) (uAvionix) -- [FLARM](https://flarm.com/products/uav/atom-uav-flarm-for-drones/) +- [FLARM](https://www.flarm.com/en/drones/) ## Налаштування програмного забезпечення diff --git a/docs/uk/ros2/px4_ros2_control_interface.md b/docs/uk/ros2/px4_ros2_control_interface.md index 13252a0f57..8597ea0532 100644 --- a/docs/uk/ros2/px4_ros2_control_interface.md +++ b/docs/uk/ros2/px4_ros2_control_interface.md @@ -14,7 +14,7 @@ At the time of writing, parts of the PX4 ROS 2 Control Interface are experimenta ::: -[PX4 ROS 2 Interface бібліотека](../ros2/px4_ros2_interface_lib.md) - це бібліотека C++++, яка спрощує контроль PX4 з ROS 2. +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library (with Python bindings) that simplifies controlling PX4 from ROS 2. Розробники використовують бібліотеку для створення і динамічної реєстрації режимів, написаних за допомогою ROS 2. Ці режими динамічно реєструються в PX4 і здаються частиною PX4 для наземної станції або іншої зовнішньої системи. @@ -26,6 +26,12 @@ At the time of writing, parts of the PX4 ROS 2 Control Interface are experimenta PX4 ROS 2 modes are easier to implement and maintain than PX4 internal modes, and provide more resources for developers in terms of processing power and pre-existing libraries. Unless the mode is safety-critical, requires strict timing or very high update rates, or your vehicle doesn't have a companion computer, you should [consider using PX4 ROS 2 modes in preference to PX4 internal modes](../concept/flight_modes.md#internal-vs-external-modes). +:::tip +If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). +Not all classes have Python bindings yet — the [supported bindings are here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_py/src/px4_ros2). +You are welcome to add and contribute missing classes. +::: + ## Загальний огляд Ця діаграма надає концептуального уявлення про те, як режими інтерфейсу і режими керування будуть взаємодіяти з PX4. diff --git a/docs/uk/ros2/px4_ros2_interface_lib.md b/docs/uk/ros2/px4_ros2_interface_lib.md index c392c93f85..821c9b554b 100644 --- a/docs/uk/ros2/px4_ros2_interface_lib.md +++ b/docs/uk/ros2/px4_ros2_interface_lib.md @@ -7,7 +7,7 @@ На момент написання цієї статті, деякі частини бібліотеки інтерфейсу PX4 ROS 2 є експериментальними і, отже, можуть бути змінені. ::: -[PX4 ROS 2 Інтерфейс бібліотеки](https://github.com/Auterion/px4-ros2-interface-lib) є бібліотекою C+++, яка спрощує контроль і взаємодіє з PX4 з ROS 2. +The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. The library provides three high-level interfaces for developers: diff --git a/docs/uk/vtx/index.md b/docs/uk/vtx/index.md new file mode 100644 index 0000000000..8206293080 --- /dev/null +++ b/docs/uk/vtx/index.md @@ -0,0 +1,287 @@ +# Analog Video Transmitters + +Analog Video Transmitters (VTX) can be controlled by PX4 via a half-duplex UART connection implementing the SmartAudio v1, v2, and v2.1 and Tramp protocols. + +The protocols allow writing and reading: + +- device status. +- transmission frequency in MHz or via band and channel index. +- transmission power in dBm or mW. +- operation modes. + +VTX settings are controlled by parameters and optionally via RC AUX channels or CRSF MSP commands. +The driver stores frequency and power tables that map band/channel indices to actual transmission values. +Configuration is device-specific and set up using the command line interface. + +## Початок роботи + +Connect the SmartAudio or Tramp pin of the VTX to the TX pin of a free serial port on the flight controller. +Then set the following parameters: + +- `VTX_SER_CFG`: Select the serial port used for VTX communication. +- `VTX_DEVICE`: Selects the VTX device (generic SmartAudio/Tramp or a specific device). + +Note that since the VTX communication is half-duplex, you can, for example, use the single-pin Radio Controller port for the VTX and use a full duplex TELEM port for CRSF communication. + +You should now be able to see the VTX device in the driver status: + +``` +nsh> vtx status +INFO [vtx] UART device: /dev/ttyS4 +INFO [vtx] VTX table "UNINITIALIZED": +INFO [vtx] Power levels: +INFO [vtx] RC mapping: Disabled +INFO [vtx] Parameters: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 0 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 = 0 mW +INFO [vtx] pit mode: off +INFO [vtx] SmartAudio v2: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 6110 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 mW +INFO [vtx] pit mode: on +INFO [vtx] lock: unlocked +``` + +:::warning +Without a configured power table, power mappings are unknown and default to 0 mW. +Some VTX devices enter pit mode when power is set to 0, regardless of the `VTX_PIT_MODE` parameter. +::: + +## VTX Table Configuration + +The VTX table stores frequency and power mappings for your specific device. + +The manufacturer usually provides this information in the form of a JSON file that can be translated into a [Betaflight CLI command set](https://www.betaflight.com/docs/development/VTX#vtx-table) that this driver implements for compatibility. + +### Power Level Configuration + +``` +# Set table name ≤16 characters +vtxtable name "Peak THOR T67" + +# Set the power values that are sent to the VTX for each power level index +# Note: SmartAudio v1 and v2 use index values! +vtxtable powervalues 0 1 2 3 4 +# Note: SmartAudio v2.1 uses dBm values instead! +# vtxtable powervalues 14 23 27 30 35 +# Note: Tramp uses mW values instead! +# vtxtable powervalues 25 200 500 1000 3000 + +# Set the corresponding power labels for each power level index ≤4 characters. +# These are used for status reporting. +vtxtable powerlabels 25 200 500 1W 3W + +# Set number of power levels +vtxtable powerlevels 5 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 5 power levels. + +```nsh> vtxtable status +INFO [vtxtable] VTX table "Peak THOR T67": +INFO [vtxtable] Power levels: +INFO [vtxtable] 1: 0 = 25 +INFO [vtxtable] 2: 1 = 200 +INFO [vtxtable] 3: 2 = 500 +INFO [vtxtable] 4: 3 = 1W +INFO [vtxtable] 5: 4 = 3W +``` + +### Frequency Table Configuration + +``` +# Set the name of each band and the frequencies of each channel +vtxtable band 1 BAND_A A FACTORY 6110 6130 6150 6170 6190 6210 6230 6250 +vtxtable band 2 BAND_B B FACTORY 6270 6290 6310 6330 6350 6370 6390 6410 +vtxtable band 3 BAND_E E FACTORY 6430 6450 6470 6490 6510 6530 6550 6570 +vtxtable band 4 BAND_F F FACTORY 6590 6610 6630 6650 6670 6690 6710 6730 +vtxtable band 5 BAND_R R FACTORY 6750 6770 6790 6810 6830 6850 6870 6890 +vtxtable band 6 BAND_P P FACTORY 6910 6930 6950 6970 6990 7010 7030 7050 +vtxtable band 7 BAND_H H FACTORY 7070 7090 7110 7130 7150 7170 7190 7210 +vtxtable band 8 BAND_U U FACTORY 6115 6265 6425 6585 6745 6905 7065 7185 + +# Set number of bands and channels +vtxtable bands 8 +vtxtable channels 8 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 8 bands and 8 channels. +Note that FACTORY sends the band and channel indexes to the VTX device and they use their internal frequency mapping. In this mode the frequency is just for indication purposes. +In contrast, CUSTOM would send the actual frequency values to the VTX device, but not all devices support this mode. +Setting a frequency to zero will skip setting it. + +``` +nsh> vtxtable status +INFO [vtxtable] VTX table 8x8: Peak THOR T67 +INFO [vtxtable] A: BAND_A = 6110 6130 6150 6170 6190 6210 6230 6250 +INFO [vtxtable] B: BAND_B = 6270 6290 6310 6330 6350 6370 6390 6410 +INFO [vtxtable] E: BAND_E = 6430 6450 6470 6490 6510 6530 6550 6570 +INFO [vtxtable] F: BAND_F = 6590 6610 6630 6650 6670 6690 6710 6730 +INFO [vtxtable] R: BAND_R = 6750 6770 6790 6810 6830 6850 6870 6890 +INFO [vtxtable] P: BAND_P = 6910 6930 6950 6970 6990 7010 7030 7050 +INFO [vtxtable] H: BAND_H = 7070 7090 7110 7130 7150 7170 7190 7210 +INFO [vtxtable] U: BAND_U = 6115 6265 6425 6585 6745 6905 7065 7185 +``` + +### Table Constraints + +Maximum table dimensions: + +- ≤24 bands each with ≤16 channels and ≤32GHz frequency values. +- ≤16 power levels. +- ≤16 characters table name. +- ≤12 characters band name and 1 character band letter. +- ≤4 characters power label length (to support "2.5W"). + +## AUX Channel Mapping + +The AUX mapping feature allows you to control VTX settings using RC AUX channels. +Each mapping entry defines an AUX channel range that triggers a specific VTX configuration. + +To enable AUX mapping, set `VTX_MAP_CONFIG` to one of the following values: + +- `0`: Disabled +- `1`: Disabled (reserved for CRSF MSP integration) +- `2`: Map AUX channels to power level control only +- `3`: Map AUX channels to band and channel control only +- `4`: Map AUX channels to all settings (power, band, and channel) + +### Configuring AUX Map Entries + +Use the following command format to add mapping entries: + +``` +vtxtable +``` + +Параметри: + +- `index`: Map entry index (0-159) +- `aux_channel`: AUX channel number (3-19, where AUX1=3) +- `band`: Target band (1-24, or 0 to leave unchanged) +- `channel`: Target channel (1-16, or 0 to leave unchanged) +- `power`: Power level (1-16, 0 to leave unchanged, or -1 for pit mode) +- `start_pwm`: Start of PWM range in microseconds (typically 900-2100) +- `end_pwm`: End of PWM range in microseconds (typically 900-2100) + +:::info +AUX channel numbering starts from 3 (AUX1=channel 3) to account for the first four RC channels 0-3 used for flight control. +::: + +Example configuration for a 6-position dial controlling band/channel on AUX4 (channel 7): + +``` +vtx 0 7 7 1 0 900 1025 +vtx 1 7 7 2 0 1025 1100 +vtx 2 7 7 4 0 1100 1175 +vtx 3 7 7 6 0 1175 1225 +vtx 4 7 7 8 0 1225 1300 +vtx 5 7 3 8 0 1300 2100 +``` + +Example configuration for power control on AUX3 (channel 6): + +``` +vtxtable 16 6 0 0 -1 900 1250 +vtxtable 17 6 0 0 1 1250 1525 +vtxtable 18 6 0 0 2 1525 1650 +vtxtable 19 6 0 0 3 1650 1875 +vtxtable 20 6 0 0 4 1875 2010 +``` + +Save the configuration with: + +``` +vtxtable save +``` + +The map status can be verified with `vtxtable status`. + +## CRSF MSP Integration + +When using a CRSF receiver with MSP support, you can control VTX settings directly from your transmitter using MSP commands sent over the CRSF link. +This feature must be enabled at compile time with the `VTX_CRSF_MSP_SUPPORT` Kconfig option. + +To enable CRSF MSP control, set `VTX_MAP_CONFIG` to one of: + +- `1`: MSP controls both frequency (band/channel) and power +- `2`: MSP controls frequency (band/channel) only, AUX controls power +- `3`: MSP controls power only, AUX controls band/channel + +When MSP integration is active, the driver responds to `MSP_SET_VTX_CONFIG` (0x59) commands. +The transmitter can send band, channel, frequency, power level, and pit mode settings via MSP, which are automatically mapped to the corresponding PX4 parameters. + +:::tip +The MSP integration allows seamless VTX control from transmitters that support VTX configuration via Lua scripts or built-in VTX menus without requiring additional hardware switches. +::: + +## Build Configuration + +Both the VTX driver and VTX table support are configured via Kconfig options. + +Key configuration options: + +- `VTX_CRSF_MSP_SUPPORT`: Enables CRSF MSP command support (default: disabled) +- `VTXTABLE_CONFIG_FILE`: File path for persistent configuration (default: `/fs/microsd/vtx_config`) +- `VTXTABLE_AUX_MAP`: Enables AUX channel mapping (default: disabled) + +## Parameter Reference + +### VTX Settings Parameters + +- `VTX_BAND` (0-23): Frequency band selection (Band 1-24 in UI) +- `VTX_CHANNEL` (0-15): Channel within band (Channel 1-16 in UI) +- `VTX_FREQUENCY` (0-32000): Direct frequency in MHz (overrides band/channel when non-zero) +- `VTX_POWER` (0-15): Power level (Level 1-16 in UI, as configured in table) +- `VTX_PIT_MODE` (boolean): Pit mode for reduced power (default: disabled) + +### Налаштування параметрів + +- `VTX_SER_CFG`: Serial port assignment for VTX communication +- `VTX_MAP_CONFIG`: Controls how VTX settings are mapped: + - Without `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: Disabled + - `2`: AUX controls power only + - `3`: AUX controls band/channel only + - `4`: AUX controls both power and band/channel + - With `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: MSP controls both frequency and power + - `2`: MSP controls frequency, AUX controls power + - `3`: MSP controls power, AUX controls band/channel + - `4`: Not used with MSP support +- `VTX_DEVICE`: Device-specific configuration (see below) + +## Device-Specific Configuration + +The `VTX_DEVICE` parameter allows device-specific workarounds. +It encodes both the protocol type and device variant: + +- Low byte (bits 0-7): Protocol selection + - `0`: SmartAudio (default) + - `1`: Tramp +- High byte (bits 8-15): Device-specific variant + - `0`: Generic device + - `20`: Peak THOR T67 + - `40`: Rush Max Solo + +### Known Device Workarounds + +**Peak THOR T67** (`VTX_DEVICE` = 5120): +This device incorrectly reports pit mode status but otherwise functions normally. +The driver applies a workaround to override the reported status with the actual configured state. + +For generic devices, use `VTX_DEVICE` = 0 (SmartAudio) or `VTX_DEVICE` = 1 (Tramp). From e2e89def7ea4bdfaa861009c6d6d9e25c89cf39f Mon Sep 17 00:00:00 2001 From: PX4 Build Bot Date: Mon, 2 Feb 2026 08:19:45 +1100 Subject: [PATCH 30/71] New Crowdin translations - zh-CN (#26398) Co-authored-by: Crowdin Bot --- docs/zh/SUMMARY.md | 3 + docs/zh/config_vtol/index.md | 1 + docs/zh/config_vtol/vtol_ice_shedding.md | 22 ++ docs/zh/contribute/code.md | 2 +- docs/zh/modules/hello_sky.md | 6 +- docs/zh/modules/modules_communication.md | 2 +- .../mc_neural_network_control.md | 6 +- docs/zh/neural_networks/raptor.md | 2 +- docs/zh/peripherals/adsb_flarm.md | 2 +- docs/zh/ros2/px4_ros2_control_interface.md | 8 +- docs/zh/ros2/px4_ros2_interface_lib.md | 2 +- docs/zh/vtx/index.md | 287 ++++++++++++++++++ 12 files changed, 335 insertions(+), 8 deletions(-) create mode 100644 docs/zh/config_vtol/vtol_ice_shedding.md create mode 100644 docs/zh/vtx/index.md diff --git a/docs/zh/SUMMARY.md b/docs/zh/SUMMARY.md index 440ee6c682..6af00c4160 100644 --- a/docs/zh/SUMMARY.md +++ b/docs/zh/SUMMARY.md @@ -93,6 +93,7 @@ - [VTOL后转换调参](config_vtol/vtol_back_transition_tuning.md) - [没有空速传感器的VTOL ](config_vtol/vtol_without_airspeed_sensor.md) - [垂直起降风向仪](config_vtol/vtol_weathervane.md) + - [VTOL Ice Shedding](config_vtol/vtol_ice_shedding.md) - [飞行模式](flight_modes_vtol/index.md) - [Mission Mode (VTOL)](flight_modes_vtol/mission.md) - [Return Mode (VTOL)](flight_modes_vtol/return.md) @@ -361,6 +362,8 @@ - [Satellite Comms (Iridium/RockBlock)](advanced_features/satcom_roadblock.md) + - [Analog Video Transmitters](vtx/index.md) + - [Power Systems](power_systems/index.md) - [Battery Estimation Tuning](config/battery.md) - [Battery Chemistry Overview](power_systems/battery_chemistry.md) diff --git a/docs/zh/config_vtol/index.md b/docs/zh/config_vtol/index.md index fe5ff34801..24096ad139 100644 --- a/docs/zh/config_vtol/index.md +++ b/docs/zh/config_vtol/index.md @@ -9,3 +9,4 @@ Then perform VTOL-specific configuration and tuning: - [Back-transition Tuning](../config_vtol/vtol_back_transition_tuning.md) - [VTOL w/o Airspeed Sensor](../config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](../config_vtol/vtol_weathervane.md) +- [Ice Shedding](../config_vtol/vtol_ice_shedding.md) diff --git a/docs/zh/config_vtol/vtol_ice_shedding.md b/docs/zh/config_vtol/vtol_ice_shedding.md new file mode 100644 index 0000000000..6884211c7b --- /dev/null +++ b/docs/zh/config_vtol/vtol_ice_shedding.md @@ -0,0 +1,22 @@ +# VTOL Ice Shedding feature + +## 综述 + +Ice shedding is a feature that periodically spins unused motors in fixed-wing +flight, to break off any ice that is starting to build up in the motors while it +is still feasible to do so. + +It is configured by the paramter `CA_ICE_PERIOD`. When it is 0, the feature is +disabled, when it is above 0, it sets the duration of the ice shedding cycle in +seconds. In each cycle, the rotors are spun for two seconds at a motor output of +0.01. + +:::warning +When enabling the feature on a new airframe, there is the risk of producing +torques that disturb the fixed-wing rate controller. To mitigate this risk: + +- Set your `PWM_MIN` values correctly, so that the motor output 0.01 actually + produces 1% thrust +- Be prepared to take control and switch back to multicopter + +::: diff --git a/docs/zh/contribute/code.md b/docs/zh/contribute/code.md index 386458a6f0..793a629099 100644 --- a/docs/zh/contribute/code.md +++ b/docs/zh/contribute/code.md @@ -34,7 +34,7 @@ If you update an existing file you are not required to make the whole file compl ### Line Length -- Maximum line length is 120 characters. +- Maximum line length is 140 characters. ### File Extensions diff --git a/docs/zh/modules/hello_sky.md b/docs/zh/modules/hello_sky.md index e1c185d810..87e4ebffa4 100644 --- a/docs/zh/modules/hello_sky.md +++ b/docs/zh/modules/hello_sky.md @@ -89,15 +89,19 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too ``` :::tip + The main function must be named `_main` and exported from the module as shown. + ::: :::tip + `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + ::: 3. Create and open a new _cmake_ definition file named **CMakeLists.txt**. @@ -166,7 +170,7 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too 4. Create and open a new _Kconfig_ definition file named **Kconfig** and define your symbol for naming (see [Kconfig naming convention](../hardware/porting_guide_config.md#px4-kconfig-symbol-naming-convention)). 复制下面的文本: - ``` + ```text menuconfig EXAMPLES_PX4_SIMPLE_APP bool "px4_simple_app" default n diff --git a/docs/zh/modules/modules_communication.md b/docs/zh/modules/modules_communication.md index 86a9eb78a6..03ca66aa5e 100644 --- a/docs/zh/modules/modules_communication.md +++ b/docs/zh/modules/modules_communication.md @@ -35,7 +35,7 @@ Source: [modules/mavlink](https://github.com/PX4/PX4-Autopilot/tree/main/src/mod This module implements the MAVLink protocol, which can be used on a Serial link or UDP network connection. It communicates with the system via uORB: some messages are directly handled in the module (eg. mission protocol), others are published via uORB (eg. vehicle_command). 流(Stream)被用来以特定速率发送周期性的消息,例如飞机姿态信息。 -Streams are used to send periodic messages with a specific rate, such as the vehicle attitude. When starting the mavlink instance, a mode can be specified, which defines the set of enabled streams with their rates. For a running instance, streams can be configured via mavlink stream command. +When starting the mavlink instance, a mode can be specified, which defines the set of enabled streams with their rates. For a running instance, streams can be configured via `mavlink stream` command. 可以存在多个该模块的实例,每个实例连接到一个串口设备或者网络端口。 diff --git a/docs/zh/neural_networks/mc_neural_network_control.md b/docs/zh/neural_networks/mc_neural_network_control.md index 5e06f6a4c5..8e0e94c327 100644 --- a/docs/zh/neural_networks/mc_neural_network_control.md +++ b/docs/zh/neural_networks/mc_neural_network_control.md @@ -22,7 +22,11 @@ If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tu This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). +:::tip +For more information, see the Masters thesis from which this module was created: [Deep Reinforcement Learning for Embedded Control Policies for Aerial Vehicles](https://nva.sikt.no/registration/019b26689144-efeebae8-84d6-4413-ad7f-9aceb4ff7374). + +In addition, the (Norwegian) website [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/) has a youtube video and a workshop paper . +::: ## Neural Network PX4 Firmware diff --git a/docs/zh/neural_networks/raptor.md b/docs/zh/neural_networks/raptor.md index a2c94576a6..e7b9c60d68 100644 --- a/docs/zh/neural_networks/raptor.md +++ b/docs/zh/neural_networks/raptor.md @@ -35,7 +35,7 @@ The method we developed for training the RAPTOR policy is called Meta-Imitation You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: - + For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). diff --git a/docs/zh/peripherals/adsb_flarm.md b/docs/zh/peripherals/adsb_flarm.md index b3764e4796..36d2c728be 100644 --- a/docs/zh/peripherals/adsb_flarm.md +++ b/docs/zh/peripherals/adsb_flarm.md @@ -11,7 +11,7 @@ PX4 traffic avoidance works with ADS-B or FLARM products that supply transponder It has been tested with the following devices: - [PingRX ADS-B Receiver](https://uavionix.com/product/pingrx-pro/) (uAvionix) -- [FLARM](https://flarm.com/products/uav/atom-uav-flarm-for-drones/) +- [FLARM](https://www.flarm.com/en/drones/) ## 硬件安装 diff --git a/docs/zh/ros2/px4_ros2_control_interface.md b/docs/zh/ros2/px4_ros2_control_interface.md index 625ae209b8..182b18b45a 100644 --- a/docs/zh/ros2/px4_ros2_control_interface.md +++ b/docs/zh/ros2/px4_ros2_control_interface.md @@ -14,7 +14,7 @@ Experimental ::: -这[PX4 ROS 2接口库](../ros2/px4_ros2_interface_lib.md)是一个 C++ 库,可简化从 ROS 2 控制 PX4 的操作。 +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library (with Python bindings) that simplifies controlling PX4 from ROS 2. 开发者可使用该库创建并动态注册以 ROS 2 编写的模式。 这些模式会动态注册到 PX4 中,并且对于地面站或其他外部系统而言,它们看起来就像是 PX4 的一部分。 @@ -26,6 +26,12 @@ Experimental PX4 ROS 2 模式相较于 PX4 内部模式,更易于实现和维护,并且在处理能力与既有代码库资源方面,能为开发者提供更丰富的支持。 除非该模式属于安全关键型、对时序有严格要求或需要极高的更新速率,或者你的飞行器没有搭载伴随计算机,否则你应优先[考虑使用 PX4 ROS 2 模式,而非 PX4 内部模式](../concept/flight_modes.md#internal-vs-external-modes)。 +:::tip +If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). +Not all classes have Python bindings yet — the [supported bindings are here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_py/src/px4_ros2). +You are welcome to add and contribute missing classes. +::: + ## 综述 该图从概念层面概述了控制接口模式与模式执行器如何与 PX4 进行交互。 diff --git a/docs/zh/ros2/px4_ros2_interface_lib.md b/docs/zh/ros2/px4_ros2_interface_lib.md index e73f8efffe..215c9c14f7 100644 --- a/docs/zh/ros2/px4_ros2_interface_lib.md +++ b/docs/zh/ros2/px4_ros2_interface_lib.md @@ -7,7 +7,7 @@ Experimental 在撰写本文时,PX4 ROS 2 接口库的部分内容仍处于试验阶段,因此可能会发生变动。 ::: -[PX4 ROS 2 接口库 ](https://github.com/Auterion/px4-ros2-interface-lib)是一个 C++ 库,可简化从 ROS 2 对 PX4 进行控制和交互的操作。 +The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. 该库为开发者提供了两个高级接口。 diff --git a/docs/zh/vtx/index.md b/docs/zh/vtx/index.md new file mode 100644 index 0000000000..b39ad4c57b --- /dev/null +++ b/docs/zh/vtx/index.md @@ -0,0 +1,287 @@ +# Analog Video Transmitters + +Analog Video Transmitters (VTX) can be controlled by PX4 via a half-duplex UART connection implementing the SmartAudio v1, v2, and v2.1 and Tramp protocols. + +The protocols allow writing and reading: + +- device status. +- transmission frequency in MHz or via band and channel index. +- transmission power in dBm or mW. +- operation modes. + +VTX settings are controlled by parameters and optionally via RC AUX channels or CRSF MSP commands. +The driver stores frequency and power tables that map band/channel indices to actual transmission values. +Configuration is device-specific and set up using the command line interface. + +## 入门指南 + +Connect the SmartAudio or Tramp pin of the VTX to the TX pin of a free serial port on the flight controller. +Then set the following parameters: + +- `VTX_SER_CFG`: Select the serial port used for VTX communication. +- `VTX_DEVICE`: Selects the VTX device (generic SmartAudio/Tramp or a specific device). + +Note that since the VTX communication is half-duplex, you can, for example, use the single-pin Radio Controller port for the VTX and use a full duplex TELEM port for CRSF communication. + +You should now be able to see the VTX device in the driver status: + +``` +nsh> vtx status +INFO [vtx] UART device: /dev/ttyS4 +INFO [vtx] VTX table "UNINITIALIZED": +INFO [vtx] Power levels: +INFO [vtx] RC mapping: Disabled +INFO [vtx] Parameters: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 0 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 = 0 mW +INFO [vtx] pit mode: off +INFO [vtx] SmartAudio v2: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 6110 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 mW +INFO [vtx] pit mode: on +INFO [vtx] lock: unlocked +``` + +:::warning +Without a configured power table, power mappings are unknown and default to 0 mW. +Some VTX devices enter pit mode when power is set to 0, regardless of the `VTX_PIT_MODE` parameter. +::: + +## VTX Table Configuration + +The VTX table stores frequency and power mappings for your specific device. + +The manufacturer usually provides this information in the form of a JSON file that can be translated into a [Betaflight CLI command set](https://www.betaflight.com/docs/development/VTX#vtx-table) that this driver implements for compatibility. + +### Power Level Configuration + +``` +# Set table name ≤16 characters +vtxtable name "Peak THOR T67" + +# Set the power values that are sent to the VTX for each power level index +# Note: SmartAudio v1 and v2 use index values! +vtxtable powervalues 0 1 2 3 4 +# Note: SmartAudio v2.1 uses dBm values instead! +# vtxtable powervalues 14 23 27 30 35 +# Note: Tramp uses mW values instead! +# vtxtable powervalues 25 200 500 1000 3000 + +# Set the corresponding power labels for each power level index ≤4 characters. +# These are used for status reporting. +vtxtable powerlabels 25 200 500 1W 3W + +# Set number of power levels +vtxtable powerlevels 5 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 5 power levels. + +```nsh> vtxtable status +INFO [vtxtable] VTX table "Peak THOR T67": +INFO [vtxtable] Power levels: +INFO [vtxtable] 1: 0 = 25 +INFO [vtxtable] 2: 1 = 200 +INFO [vtxtable] 3: 2 = 500 +INFO [vtxtable] 4: 3 = 1W +INFO [vtxtable] 5: 4 = 3W +``` + +### Frequency Table Configuration + +``` +# Set the name of each band and the frequencies of each channel +vtxtable band 1 BAND_A A FACTORY 6110 6130 6150 6170 6190 6210 6230 6250 +vtxtable band 2 BAND_B B FACTORY 6270 6290 6310 6330 6350 6370 6390 6410 +vtxtable band 3 BAND_E E FACTORY 6430 6450 6470 6490 6510 6530 6550 6570 +vtxtable band 4 BAND_F F FACTORY 6590 6610 6630 6650 6670 6690 6710 6730 +vtxtable band 5 BAND_R R FACTORY 6750 6770 6790 6810 6830 6850 6870 6890 +vtxtable band 6 BAND_P P FACTORY 6910 6930 6950 6970 6990 7010 7030 7050 +vtxtable band 7 BAND_H H FACTORY 7070 7090 7110 7130 7150 7170 7190 7210 +vtxtable band 8 BAND_U U FACTORY 6115 6265 6425 6585 6745 6905 7065 7185 + +# Set number of bands and channels +vtxtable bands 8 +vtxtable channels 8 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 8 bands and 8 channels. +Note that FACTORY sends the band and channel indexes to the VTX device and they use their internal frequency mapping. In this mode the frequency is just for indication purposes. +In contrast, CUSTOM would send the actual frequency values to the VTX device, but not all devices support this mode. +Setting a frequency to zero will skip setting it. + +``` +nsh> vtxtable status +INFO [vtxtable] VTX table 8x8: Peak THOR T67 +INFO [vtxtable] A: BAND_A = 6110 6130 6150 6170 6190 6210 6230 6250 +INFO [vtxtable] B: BAND_B = 6270 6290 6310 6330 6350 6370 6390 6410 +INFO [vtxtable] E: BAND_E = 6430 6450 6470 6490 6510 6530 6550 6570 +INFO [vtxtable] F: BAND_F = 6590 6610 6630 6650 6670 6690 6710 6730 +INFO [vtxtable] R: BAND_R = 6750 6770 6790 6810 6830 6850 6870 6890 +INFO [vtxtable] P: BAND_P = 6910 6930 6950 6970 6990 7010 7030 7050 +INFO [vtxtable] H: BAND_H = 7070 7090 7110 7130 7150 7170 7190 7210 +INFO [vtxtable] U: BAND_U = 6115 6265 6425 6585 6745 6905 7065 7185 +``` + +### Table Constraints + +Maximum table dimensions: + +- ≤24 bands each with ≤16 channels and ≤32GHz frequency values. +- ≤16 power levels. +- ≤16 characters table name. +- ≤12 characters band name and 1 character band letter. +- ≤4 characters power label length (to support "2.5W"). + +## AUX Channel Mapping + +The AUX mapping feature allows you to control VTX settings using RC AUX channels. +Each mapping entry defines an AUX channel range that triggers a specific VTX configuration. + +To enable AUX mapping, set `VTX_MAP_CONFIG` to one of the following values: + +- `0`: Disabled +- `1`: Disabled (reserved for CRSF MSP integration) +- `2`: Map AUX channels to power level control only +- `3`: Map AUX channels to band and channel control only +- `4`: Map AUX channels to all settings (power, band, and channel) + +### Configuring AUX Map Entries + +Use the following command format to add mapping entries: + +``` +vtxtable +``` + +Parameters: + +- `index`: Map entry index (0-159) +- `aux_channel`: AUX channel number (3-19, where AUX1=3) +- `band`: Target band (1-24, or 0 to leave unchanged) +- `channel`: Target channel (1-16, or 0 to leave unchanged) +- `power`: Power level (1-16, 0 to leave unchanged, or -1 for pit mode) +- `start_pwm`: Start of PWM range in microseconds (typically 900-2100) +- `end_pwm`: End of PWM range in microseconds (typically 900-2100) + +:::info +AUX channel numbering starts from 3 (AUX1=channel 3) to account for the first four RC channels 0-3 used for flight control. +::: + +Example configuration for a 6-position dial controlling band/channel on AUX4 (channel 7): + +``` +vtx 0 7 7 1 0 900 1025 +vtx 1 7 7 2 0 1025 1100 +vtx 2 7 7 4 0 1100 1175 +vtx 3 7 7 6 0 1175 1225 +vtx 4 7 7 8 0 1225 1300 +vtx 5 7 3 8 0 1300 2100 +``` + +Example configuration for power control on AUX3 (channel 6): + +``` +vtxtable 16 6 0 0 -1 900 1250 +vtxtable 17 6 0 0 1 1250 1525 +vtxtable 18 6 0 0 2 1525 1650 +vtxtable 19 6 0 0 3 1650 1875 +vtxtable 20 6 0 0 4 1875 2010 +``` + +Save the configuration with: + +``` +vtxtable save +``` + +The map status can be verified with `vtxtable status`. + +## CRSF MSP Integration + +When using a CRSF receiver with MSP support, you can control VTX settings directly from your transmitter using MSP commands sent over the CRSF link. +This feature must be enabled at compile time with the `VTX_CRSF_MSP_SUPPORT` Kconfig option. + +To enable CRSF MSP control, set `VTX_MAP_CONFIG` to one of: + +- `1`: MSP controls both frequency (band/channel) and power +- `2`: MSP controls frequency (band/channel) only, AUX controls power +- `3`: MSP controls power only, AUX controls band/channel + +When MSP integration is active, the driver responds to `MSP_SET_VTX_CONFIG` (0x59) commands. +The transmitter can send band, channel, frequency, power level, and pit mode settings via MSP, which are automatically mapped to the corresponding PX4 parameters. + +:::tip +The MSP integration allows seamless VTX control from transmitters that support VTX configuration via Lua scripts or built-in VTX menus without requiring additional hardware switches. +::: + +## Build Configuration + +Both the VTX driver and VTX table support are configured via Kconfig options. + +Key configuration options: + +- `VTX_CRSF_MSP_SUPPORT`: Enables CRSF MSP command support (default: disabled) +- `VTXTABLE_CONFIG_FILE`: File path for persistent configuration (default: `/fs/microsd/vtx_config`) +- `VTXTABLE_AUX_MAP`: Enables AUX channel mapping (default: disabled) + +## Parameter Reference + +### VTX Settings Parameters + +- `VTX_BAND` (0-23): Frequency band selection (Band 1-24 in UI) +- `VTX_CHANNEL` (0-15): Channel within band (Channel 1-16 in UI) +- `VTX_FREQUENCY` (0-32000): Direct frequency in MHz (overrides band/channel when non-zero) +- `VTX_POWER` (0-15): Power level (Level 1-16 in UI, as configured in table) +- `VTX_PIT_MODE` (boolean): Pit mode for reduced power (default: disabled) + +### Configuration Parameters + +- `VTX_SER_CFG`: Serial port assignment for VTX communication +- `VTX_MAP_CONFIG`: Controls how VTX settings are mapped: + - Without `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: Disabled + - `2`: AUX controls power only + - `3`: AUX controls band/channel only + - `4`: AUX controls both power and band/channel + - With `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: MSP controls both frequency and power + - `2`: MSP controls frequency, AUX controls power + - `3`: MSP controls power, AUX controls band/channel + - `4`: Not used with MSP support +- `VTX_DEVICE`: Device-specific configuration (see below) + +## Device-Specific Configuration + +The `VTX_DEVICE` parameter allows device-specific workarounds. +It encodes both the protocol type and device variant: + +- Low byte (bits 0-7): Protocol selection + - `0`: SmartAudio (default) + - `1`: Tramp +- High byte (bits 8-15): Device-specific variant + - `0`: Generic device + - `20`: Peak THOR T67 + - `40`: Rush Max Solo + +### Known Device Workarounds + +**Peak THOR T67** (`VTX_DEVICE` = 5120): +This device incorrectly reports pit mode status but otherwise functions normally. +The driver applies a workaround to override the reported status with the actual configured state. + +For generic devices, use `VTX_DEVICE` = 0 (SmartAudio) or `VTX_DEVICE` = 1 (Tramp). From 82e3322e0cf0afc9ad640f37a0a8b639077b3fa4 Mon Sep 17 00:00:00 2001 From: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:14:47 -0900 Subject: [PATCH 31/71] vtxtable: fix KConfig type from string to bool (#26359) --- src/drivers/vtxtable/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/vtxtable/Kconfig b/src/drivers/vtxtable/Kconfig index f19d09a1dd..1fc96d9d96 100644 --- a/src/drivers/vtxtable/Kconfig +++ b/src/drivers/vtxtable/Kconfig @@ -19,7 +19,7 @@ if DRIVERS_VTXTABLE default n if !(VTXTABLE_CONFIG_FILE != "") config VTXTABLE_AUX_MAP - string "VTX Auxiliary Map" + bool "VTX Auxiliary Map" default n ---help--- Enable the AUX map for mapping AUX channel ranges to VTX From 41966774c2835f1a230fb25d45ae05ed0ccc09ba Mon Sep 17 00:00:00 2001 From: ch3at Date: Tue, 3 Feb 2026 23:38:43 +0300 Subject: [PATCH 32/71] docs: fix incorrect links in config/safety.md (#26355) Fixed incorrect links to Acro mode --- docs/en/config/safety.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/config/safety.md b/docs/en/config/safety.md index f97fb392aa..9f72f4589f 100644 --- a/docs/en/config/safety.md +++ b/docs/en/config/safety.md @@ -283,7 +283,7 @@ Acting on a detected failure during flight is deactivated by default (enable by During **takeoff** the failure detector [attitude trigger](#attitude-trigger) invokes the [disarm action](#act_disarm) if the vehicle flips (disarm kills the motors but, unlike flight termination, will not launch a parachute or perform other failure actions). Note that this check is _always enabled on takeoff_, irrespective of the `CBRK_FLIGHTTERM` parameter. -The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/altitude.md), [Acro mode (FW)](../flight_modes_fw/altitude.md), and [Manual (FW)](../flight_modes_fw/manual.md)). +The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/acro.md), [Acro mode (FW)](../flight_modes_fw/acro.md), and [Manual (FW)](../flight_modes_fw/manual.md)). ### Attitude Trigger From 1bfc0da258adf4dc3ab577df81a87026c4373454 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Wed, 4 Feb 2026 10:46:36 +1300 Subject: [PATCH 33/71] [Sponsored by CubePilot] Get CI to pass all boards (#26402) * kakutef7: try to save more flash --- boards/auterion/fmu-v6x/zenoh.px4board | 2 ++ .../kakutef7/nuttx-config/nsh/defconfig | 24 +++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/boards/auterion/fmu-v6x/zenoh.px4board b/boards/auterion/fmu-v6x/zenoh.px4board index cb14fde935..6827430786 100644 --- a/boards/auterion/fmu-v6x/zenoh.px4board +++ b/boards/auterion/fmu-v6x/zenoh.px4board @@ -1,4 +1,6 @@ # CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE is not set CONFIG_DRIVERS_UAVCAN=n CONFIG_MODULES_UXRCE_DDS_CLIENT=n +CONFIG_SYSTEMCMDS_SD_BENCH=n +CONFIG_SYSTEMCMDS_I2CDETECT=n CONFIG_MODULES_ZENOH=y diff --git a/boards/holybro/kakutef7/nuttx-config/nsh/defconfig b/boards/holybro/kakutef7/nuttx-config/nsh/defconfig index 88d57ea784..feb176891d 100644 --- a/boards/holybro/kakutef7/nuttx-config/nsh/defconfig +++ b/boards/holybro/kakutef7/nuttx-config/nsh/defconfig @@ -16,36 +16,36 @@ # CONFIG_NSH_DISABLE_CAT is not set # CONFIG_NSH_DISABLE_CD is not set # CONFIG_NSH_DISABLE_CP is not set -# CONFIG_NSH_DISABLE_DATE is not set -# CONFIG_NSH_DISABLE_DF is not set +CONFIG_NSH_DISABLE_DATE=y +CONFIG_NSH_DISABLE_DF=y # CONFIG_NSH_DISABLE_ECHO is not set # CONFIG_NSH_DISABLE_ENV is not set # CONFIG_NSH_DISABLE_EXEC is not set # CONFIG_NSH_DISABLE_EXIT is not set -# CONFIG_NSH_DISABLE_EXPORT is not set -# CONFIG_NSH_DISABLE_FREE is not set -# CONFIG_NSH_DISABLE_GET is not set +CONFIG_NSH_DISABLE_EXPORT=y +CONFIG_NSH_DISABLE_FREE=y +CONFIG_NSH_DISABLE_GET=y # CONFIG_NSH_DISABLE_HELP is not set # CONFIG_NSH_DISABLE_ITEF is not set # CONFIG_NSH_DISABLE_KILL is not set # CONFIG_NSH_DISABLE_LOOPS is not set # CONFIG_NSH_DISABLE_LS is not set -# CONFIG_NSH_DISABLE_MKDIR is not set +CONFIG_NSH_DISABLE_MKDIR=y # CONFIG_NSH_DISABLE_MKFATFS is not set # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set -# CONFIG_NSH_DISABLE_PRINTF is not set -# CONFIG_NSH_DISABLE_PS is not set -# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set -# CONFIG_NSH_DISABLE_PWD is not set +CONFIG_NSH_DISABLE_PRINTF=y +CONFIG_NSH_DISABLE_PS=y +CONFIG_NSH_DISABLE_PSSTACKUSAGE=y +CONFIG_NSH_DISABLE_PWD=y # CONFIG_NSH_DISABLE_RM is not set -# CONFIG_NSH_DISABLE_RMDIR is not set +CONFIG_NSH_DISABLE_RMDIR=y # CONFIG_NSH_DISABLE_SEMICOLON is not set # CONFIG_NSH_DISABLE_SET is not set # CONFIG_NSH_DISABLE_SLEEP is not set # CONFIG_NSH_DISABLE_SOURCE is not set # CONFIG_NSH_DISABLE_TEST is not set -# CONFIG_NSH_DISABLE_TIME is not set +CONFIG_NSH_DISABLE_TIME=y # CONFIG_NSH_DISABLE_UMOUNT is not set # CONFIG_NSH_DISABLE_UNSET is not set # CONFIG_NSH_DISABLE_USLEEP is not set From de1314f99590eb27491c84666578a29de99fecd6 Mon Sep 17 00:00:00 2001 From: Beniamino Pozzan Date: Tue, 3 Feb 2026 22:40:32 +0000 Subject: [PATCH 34/71] docs: fix badge for UXRCE_DDS_FLCTRL (#26375) Signed-off-by: Beniamino Pozzan --- docs/en/middleware/uxrce_dds.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/middleware/uxrce_dds.md b/docs/en/middleware/uxrce_dds.md index ca336a2d37..806fe0f479 100644 --- a/docs/en/middleware/uxrce_dds.md +++ b/docs/en/middleware/uxrce_dds.md @@ -324,7 +324,7 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. - - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. ::: info From e8fca6e991b78c608fe5ca8814208b366a67cd5f Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 5 Feb 2026 17:58:45 +1100 Subject: [PATCH 35/71] uORB docs parser (#24977) --- Tools/msg/generate_msg_docs.py | 880 +++++++++++++++++++++++++++++--- docs/.vitepress/theme/style.css | 41 ++ 2 files changed, 863 insertions(+), 58 deletions(-) diff --git a/Tools/msg/generate_msg_docs.py b/Tools/msg/generate_msg_docs.py index 18308aed9c..35827f4a44 100755 --- a/Tools/msg/generate_msg_docs.py +++ b/Tools/msg/generate_msg_docs.py @@ -8,6 +8,803 @@ Also generates docs/en/middleware/dds_topics.md from dds_topics.yaml import os import argparse import sys +import re + +VALID_FIELDS = { #Note, also have to add the message types as those can be fields + 'uint64', + 'uint16', + 'uint8', + 'uint32' +} + +ALLOWED_UNITS = set(["m", "m/s", "m/s^2", "(m/s)^2", "deg", "deg/s", "rad", "rad/s", "rad^2", "rpm" ,"V", "A", "mA", "mAh", "W", "dBm", "h", "s", "ms", "us", "Ohm", "MB", "Kb/s", "degC","Pa","%","-"]) +invalid_units = set() +ALLOWED_FRAMES = set(["NED","Body"]) +ALLOWED_INVALID_VALUES = set(["NaN", "0"]) +ALLOWED_CONSTANTS_NOT_IN_ENUM = set(["ORB_QUEUE_LENGTH","MESSAGE_VERSION"]) + +class Error: + def __init__(self, type, message, linenumber=None, issueString = None, field = None): + self.type = type + self.message = message + self.linenumber = linenumber + self.issueString = issueString + self.field = field + + def display_error(self): + #print(f"Debug: Error: display_error") + + + if 'trailing_whitespace' == self.type: + if self.issueString.strip(): + print(f"NOTE: Line has trailing whitespace ({self.message}: {self.linenumber}): {self.issueString}") + else: + print(f"NOTE: Line has trailing whitespace ({self.message}: {self.linenumber})") + elif 'leading_whitespace_field_or_constant' == self.type: + print(f"NOTE: Whitespace before field or constant ({self.message}: {self.linenumber}): {self.issueString}") + elif 'field_or_constant_has_multiple_whitepsace' == self.type: + print(f"NOTE: Field/constant has more than one sequential whitespace character ({self.message}: {self.linenumber}): {self.issueString}") + elif 'empty_start_line' == self.type: + print(f"NOTE: Empty line at start of file ({self.message}: {self.linenumber})") + elif 'internal_comment' == self.type: + print(f"NOTE: Internal Comment ({self.message}: {self.linenumber})\n {self.issueString}") + elif 'internal_comment_empty' == self.type: + print(f"NOTE: Empty Internal Comment ({self.message}: {self.linenumber})") + elif 'summary_missing' == self.type: + print(f"WARNING: No message description ({self.message})") + elif 'topic_error' == self.type: + print(f"NOTE: TOPIC ISSUE: {self.issueString}") + elif 'unknown_unit' == self.type: + print(f"WARNING: Unknown Unit: [{self.issueString}] on `{self.field}` ({self.message}: {self.linenumber})") + elif 'constant_not_in_assigned_enum' == self.type: + print(f"WARNING: `{self.issueString}` constant: Prefix not in `@enum` field metadata ({self.message}: {self.linenumber})") + elif 'unknown_invalid_value' == self.type: + print(f"WARNING: Unknown @invalid value: [{self.issueString}] on `{self.field}` ({self.message}: {self.linenumber})") + elif 'unknown_frame' == self.type: + print(f"WARNING: Unknown @frame: [{self.issueString}] on `{self.field}` ({self.message}: {self.linenumber})") + elif 'command_no_params_pipes' == self.type: + print(f"WARNING: `{self.field}` command has no parameters (pipes): [{self.issueString}] ({self.message}: {self.linenumber})") + elif 'command_missing_params' == self.type: + print(f"WARNING: `{self.field}` command missing params - should be 7 params surrounded by 8 pipes: [{self.issueString}] ({self.message}: {self.linenumber})") + elif 'command_too_many_params' == self.type: + print(f"WARNING: `{self.field}` command too many params (should be 7). Extras: [{self.issueString}] ({self.message}: {self.linenumber})") + + + else: + self.display_info() + + def display_info(self): + """ + Display info about an error. + Used as a fallback if error does not have specific printout in display_error() + """ + #print(f"Debug: Error: display_info") + print(f" type: {self.type}, message: {self.message}, linenumber: {self.linenumber}, issueString: {self.issueString}, field: {self.field}") + +class Enum: + def __init__(self, name, parentMessage): + self.name = name + self.parent = parentMessage + self.enumValues = dict() + + def display_info(self): + """ + Display info about an enum + """ + print(f"Debug: Enum: display_info") + print(f" name: {self.name}") + for key, value in self.enumValues.items(): + value.display_info() + +class ConstantValue: + def __init__(self, name, type, value, comment, line_number): + self.name = name.strip() + self.type = type.strip() + self.value = value.strip() + self.comment = comment + self.line_number = line_number + + if not self.value: + print(f"Debug WARNING: NO VALUE in ConstantValue: {self.name}") ## TODO make into ERROR + exit() + + # TODO if value or name are empty, error + + def display_info(self): + print(f"Debug: ConstantValue: display_info") + print(f" name: {self.name}, type: {self.type}, value: {self.value}, comment: {self.comment}, line: {self.line_number}") + + +class CommandParam: + """ + Represents an individual param in a command constant + Encapsulates parsing of the param to extract units etc. + """ + + def __init__(self, num, paramText, line_number, parentCommand): + self.paramNum = num + self.paramText = paramText.strip() + self.enum = None + self.range = None + #self.type = type + self.units = [] + self.enums = [] + self.minValue = None + self.maxValue = None + self.invalidValue = None + self.frameValue = None + self.lineNumber = line_number + self.parent = parentCommand + self.parentMessage = self.parent.parent + + match = None + if self.paramText: + match = re.match(r'^((?:\[[^\]]*\]\s*)+)(.*)$', paramText) + self.description = paramText + bracketed_part = None + if match: + bracketed_part = match.group(1).strip() # .strip() removes trailing whitespace from the bracketed part + self.description = match.group(2).strip() + if bracketed_part: + # get units + bracket_content_matches = re.findall(r'\[(.*?)\]', bracketed_part) + #print(f"DEBUG: bracket_content_matches: {bracket_content_matches}") + for item in bracket_content_matches: + item = item.strip() + if item.startswith('@'): # Not a unit: + if item.startswith('@enum'): + item = item.split(" ") + enum = item[1].strip() + if enum and enum not in self.enums: + self.enums.append(enum) + + # Create parent enum objects for any enums created in this step + for enumName in self.enums: + if not enumName in self.parentMessage.enums: + self.parentMessage.enums[enumName]=Enum(enumName,self.parentMessage) + + elif item.startswith('@range'): + item = item[6:].strip().split(",") + self.range = item + self.minValue = item[0].strip() + self.maxValue = item[1].strip() + elif item.startswith('@invalid'): + self.invalidValue = item[8:].strip() + #TODO: Do we require a description? (not currently) + if self.invalidValue.split(" ")[0] not in ALLOWED_INVALID_VALUES: + print(f"TODO: Command param do not support @invalid: {self.invalidValue}") + """ + error = Error("unknown_invalid_value", self.parent.filename, self.lineNumber, self.invalidValue, self.name) + #error.display_error() + if not "unknown_invalid_value" in self.parent.errors: + self.parent.errors["unknown_invalid_value"] = [] + self.parent.errors["unknown_invalid_value"].append(error) + """ + + elif item.startswith('@frame'): + self.frameValue = item[6:].strip() + print(f"TODO: Command param do not support @frame: {self.frameValue}") + """ + if self.frameValue not in ALLOWED_FRAMES: + error = Error("unknown_frame", self.parent.filename, self.lineNumber, self.frameValue, self.name) + #error.display_error() + if not "unknown_frame" in self.parent.errors: + self.parent.errors["unknown_frame"] = [] + self.parent.errors["unknown_frame"].append(error) + """ + else: + print(f"WARNING: Unhandled metadata in message comment: {item}") + # TODO - report errors for different kinds of metadata + exit() + + else: # bracket is a unit + unit = item.strip() + + if item == "-": + unit = "" + + if unit and unit not in self.units: + self.units.append(unit) + + if unit not in ALLOWED_UNITS: + invalid_units.add(unit) + error = Error("unknown_unit", self.parentMessage.filename, self.lineNumber, unit, self.parent.name) + #error.display_error() + if not "unknown_unit" in self.parentMessage.errors: + self.parentMessage.errors["unknown_unit"] = [] + self.parentMessage.errors["unknown_unit"].append(error) + + + def display_info(self): + print(f"Debug: CommandParam: display_info") + print(f" id: {self.paramNum}") + print(f" paramText: {self.paramText}\n unit: {self.units}\n enums: {self.enums}\n lineNumber: {self.lineNumber}\n range: {self.range}\n minValue: {self.minValue}\n maxValue: {self.maxValue}\n invalidValue: {self.invalidValue}\n frameValue: {self.frameValue}\n parent: {self.parent}\n ") + + + +class CommandConstant: + """ + Represents a constant that is a command definition. + Encapsulates parsing of the command format. + The individual params are further parsed in CommandParam + """ + def __init__(self, name, type, value, comment, line_number, parentMessage): + self.name = name.strip() + self.type = type.strip() + self.value = value.strip() + self.comment = comment + self.line_number = line_number + self.parent = parentMessage + + self.description = self.comment + self.param1 = None + self.param2 = None + self.param3 = None + self.param4 = None + self.param5 = None + self.param6 = None + self.param7 = None + + if not self.value: + print(f"Debug WARNING: NO VALUE in CommandConstant: {self.name}") ## TODO make into ERROR + exit() + + if not self.comment: # This is an bug for a command + #print(f"Debug WARNING: NO COMMENT in CommandConstant: {self.name}") ## TODO make into ERROR + return + + # Parse command comment to get the description and parameters. + # print(f"Debug CommandConstant: {self.comment}") + if not "|" in self.comment: + # This is an error for a command constant + error = Error("command_no_params_pipes", self.parent.filename, self.line_number, self.comment, self.name) + #error.display_error() + if not "command_no_params_pipes" in self.parent.errors: + self.parent.errors["command_no_params_pipes"] = [] + self.parent.errors["command_no_params_pipes"].append(error) + return + + # Split on pipes + commandSplit = self.comment.split("|") + if len(commandSplit) < 9: + # Should 7 pipes, so each command is fully surrounded + error = Error("command_missing_params", self.parent.filename, self.line_number, self.comment, self.name) + #error.display_error() + if not "command_missing_params" in self.parent.errors: + self.parent.errors["command_missing_params"] = [] + self.parent.errors["command_missing_params"].append(error) + + self.description = commandSplit[0].strip() + self.description = self.description if self.description else None + + params_to_update = commandSplit[1:8] + + for i, value in enumerate(params_to_update, start=1): + if value.strip(): + # parse the param + param = CommandParam(i, value, self.line_number, self) + #param.display_info() # DEBUG CODE XXX + setattr(self, f"param{i}", param) + # parse the param + + if len(commandSplit) > 8: + extras = commandSplit[8:] + error = Error("command_too_many_params", self.parent.filename, self.line_number, extras, self.name) + if not "command_too_many_params" in self.parent.errors: + self.parent.errors["command_too_many_params"] = [] + self.parent.errors["command_too_many_params"].append(error) + + + # TODO if value or name are empty, error + + def markdown_out(self): + #print("DEBUG: CommandConstant.markdown_out") + output = f"""### {self.name} ({self.value}) + +{self.description} + +Param | Units | Range/Enum | Description +--- | --- | --- | --- +""" + for i in range(1, 8): + attr_name = f"param{i}" + # getattr returns None if the attribute doesn't exist + val = getattr(self, attr_name, None) + + if val is not None: + rangeVal = "" + if val.minValue or val.maxValue: + rangeVal = f"[{val.minValue if val.minValue else '-'} : {val.maxValue if val.maxValue else '-' }]" + + output+=f"{i} | {", ".join(val.units)}|{', '.join(f"[{e}](#{e})" for e in val.enums)}{rangeVal} | {val.description}\n" + else: + output+=f"{i} | | | ?\n" + + output+=f"\n" + return output + + + def display_info(self): + print(f"Debug: CommandConstant: display_info") + print(f" name: {self.name}, type: {self.type}, value: {self.value}, comment: {self.comment}, line: {self.line_number}") + print(f" description: {self.description}\n param1: {self.param1}\n param2: {self.param2}\n param3: {self.param3}\n param4: {self.param4}\n param5: {self.param5}\n param6: {self.param6}\n param7: {self.param7}") + +class MessageField: + """ + Represents a field. + Encapsulates parsing of the field information. + """ + def __init__(self, name, type, comment, line_number, parentMessage): + self.name = name + self.type = type + self.comment = comment + self.unit = None + self.enums = None + self.minValue = None + self.maxValue = None + self.invalidValue = None + self.frameValue = None + self.lineNumber = line_number + self.parent = parentMessage + + #print(f"MessageComment: {comment}") + match = None + if self.comment: + match = re.match(r'^((?:\[[^\]]*\]\s*)+)(.*)$', comment) + self.description = comment + bracketed_part = None + if match: + bracketed_part = match.group(1).strip() # .strip() removes trailing whitespace from the bracketed part + self.description = match.group(2).strip() + if bracketed_part: + # get units + bracket_content_matches = re.findall(r'\[(.*?)\]', bracketed_part) + #print(f"bracket_content_matches: {bracket_content_matches}") + for item in bracket_content_matches: + item = item.strip() + if item.startswith('@'): # Not a unit: + if item.startswith('@enum'): + item = item.split(" ") + self.enums = item[1:] + # Create parent enum objects + for enumName in self.enums: + if not enumName in parentMessage.enums: + parentMessage.enums[enumName]=Enum(enumName,parentMessage) + elif item.startswith('@range'): + item = item[6:].strip().split(",") + self.minValue = item[0].strip() + self.maxValue = item[1].strip() + elif item.startswith('@invalid'): + self.invalidValue = item[8:].strip() + #TODO: Do we require a description? (not currently) + if self.invalidValue.split(" ")[0] not in ALLOWED_INVALID_VALUES: + error = Error("unknown_invalid_value", self.parent.filename, self.lineNumber, self.invalidValue, self.name) + #error.display_error() + if not "unknown_invalid_value" in self.parent.errors: + self.parent.errors["unknown_invalid_value"] = [] + self.parent.errors["unknown_invalid_value"].append(error) + elif item.startswith('@frame'): + self.frameValue = item[6:].strip() + if self.frameValue not in ALLOWED_FRAMES: + error = Error("unknown_frame", self.parent.filename, self.lineNumber, self.frameValue, self.name) + #error.display_error() + if not "unknown_frame" in self.parent.errors: + self.parent.errors["unknown_frame"] = [] + self.parent.errors["unknown_frame"].append(error) + else: + print(f"WARNING: Unhandled metadata in message comment: {item}") + # TODO - report errors for different kinds of metadata + exit() + + else: # bracket is a unit + self.unit = item + + if self.unit not in ALLOWED_UNITS: + invalid_units.add(self.unit) + error = Error("unknown_unit", self.parent.filename, self.lineNumber, self.unit, self.name) + #error.display_error() + if not "unknown_unit" in self.parent.errors: + self.parent.errors["unknown_unit"] = [] + self.parent.errors["unknown_unit"].append(error) + + if item == "-": + self.unit = "" + + + def display_info(self): + print(f"Debug: MessageField: display_info") + print(f" name: {self.name}, type: {self.type}, description: {self.description}, enums: {self.enums}, minValue: {self.minValue}, maxValue: {self.maxValue}, invalidValue: {self.invalidValue}, frameValue: {self.frameValue}") + + +class UORBMessage: + """ + Represents a whole message, including fields, enums, commands, constants. + The parser function delegates the parsing of each part of the message to + more appropriate classes, once the specific type of line has been identified. + """ + + def __init__(self, filename): + + self.filename = filename + msg_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../msg") + self.msg_filename = os.path.join(msg_path, self.filename) + self.name = os.path.splitext(os.path.basename(msg_file))[0] + self.shortDescription = "" + self.longDescription = "" + self.fields = [] + self.constantFields = dict() + self.commandConstants = dict() + self.enums = dict() + self.output_file = os.path.join(output_dir, f"{self.name}.md") + self.topics = [] + self.errors = dict() + + self.parseFile() + + if args.errors: + #print(f"DEBUG: args.errors: {args.errors}") + if args.error_messages: + messages = args.error_messages.split(" ") + #print(f"DEBUG: args.errors: {messages},self.name: {self.name}") + if self.name in messages: + self.reportErrors() + #print(f"Debug: {self.name} in {messages}") + else: + self.reportErrors() + + def reportErrors(self): + #print(f"Debug: UORBMessage: reportErrors()") + for errorType, errors in self.errors.items(): + for error in errors: + error.display_error() + + def markdown_out(self): + #print(f"Debug: UORBMessage: markdown_out()") + + # Add page header (forces wide pages) + markdown = f"""--- +pageClass: is-wide-page +--- + +# {self.name} (UORB message) + +""" + ## Append description info if present + markdown += f"{self.shortDescription}\n\n" if self.shortDescription else "" + markdown += f"{self.longDescription}\n\n" if self.longDescription else "" + + topicList = " ".join(self.topics) + markdown += f"**TOPICS:** {topicList}\n\n" + + # Generate field docs + markdown += f"## Fields\n\n" + markdown += "Name | Type | Unit [Frame] | Range/Enum | Description\n" + markdown += "--- | --- | --- | --- | ---\n" + for field in self.fields: + unit = f"{field.unit}" if field.unit else "" + frame = f"[{field.frameValue}]" if field.frameValue else "" + unit = f"{unit} {frame}" + unit.strip() + unit = f" {unit}" + + value = " " + if field.enums: + value = "" + for enum in field.enums: + value += f"[{enum}](#{enum})" + value = value.strip() + value = f"{value}" + elif field.minValue or field.maxValue: + value = f"[{field.minValue if field.minValue else '-'} : {field.maxValue if field.maxValue else '-' }]" + + description = f" {field.description}" if field.description else "" + invalid = f" (Invalid: {field.invalidValue}) " if field.invalidValue else "" + markdown += f"{field.name} | `{field.type}` |{unit}|{value}|{description}{invalid}\n" + + # Generate table for command docs + if len(self.commandConstants) > 0: + #print("DEBUGCOMMAND") + markdown += f"\n## Commands\n\n" + + """ + markdown += "Name | Type | Value | Description\n" + markdown += "--- | --- | --- |---\n" + for name, command in self.commandConstants.items(): + description = f" {command.comment} " if enum.comment else " " + markdown += f' {name} | `{command.type}` | {command.value} |{description}\n' + """ + for commandConstant in self.commandConstants.values(): + #print(commandConstant) + markdown += commandConstant.markdown_out() + + # Generate enum docs + if len(self.enums) > 0: + markdown += f"\n## Enums\n" + + for name, enum in self.enums.items(): + markdown += f"\n### {name} {{#{name}}}\n\n" + + markdown += "Name | Type | Value | Description\n" + markdown += "--- | --- | --- | ---\n" + + for enumValueName, enumValue in enum.enumValues.items(): + description = f" {enumValue.comment} " if enumValue.comment else " " + markdown += f' {enumValueName} | `{enumValue.type}` | {enumValue.value} |{description}\n' + + # Generate table for constants docs + if len(self.constantFields) > 0: + markdown += f"\n## Constants\n\n" + markdown += "Name | Type | Value | Description\n" + markdown += "--- | --- | --- |---\n" + for name, enum in self.constantFields.items(): + description = f" {enum.comment} " if enum.comment else " " + markdown += f' {name} | `{enum.type}` | {enum.value} |{description}\n' + + + + # Append msg contents to the end + with open(self.msg_filename, 'r') as source_file: + msg_contents = source_file.read() + msg_contents = msg_contents.strip() + + #Format markdown using msg name, comment, url, contents. + markdown += f""" + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/{self.filename}) + +::: details Click here to see original file + +```c +{msg_contents} +``` + +::: +""" + + with open(self.output_file, 'w') as content_file: + content_file.write(markdown) + + #exit() + + + def display_info(self): + print(f"UORBMessage: display_info") + print(f" name: {self.name}") + print(f" filename: {self.filename}, ") + print(f" msg_filename: {self.msg_filename}, ") + print(f"self.shortDescription: {self.shortDescription}") + print(f"self.longDescription: {self.longDescription}") + print(f"self.enums: {self.enums}") + + for enum, enumObject in self.enums.items(): + enumObject.display_info() + + # Output our data so far + for field in self.fields: + field.display_info() + + for enumvalue in self.constantFields: + print(enumvalue) + self.constantFields[enumvalue].display_info() + + def handleField(self, line, line_number, parentMessage): + #print(f"debug: handleField: (line): \n {line}") + # Note, here we know we don't have a comment or a topic. + # We expect it to be a field. + + # Check field doesn't have leading whitespace (trailing spaces already checked) + if line[:1].isspace(): # Returns True for ' ', '\t', '\n', '\r', etc. + #print("First character is whitespace") + error = Error("leading_whitespace_field_or_constant", self.filename, line_number, line) + if not "leading_whitespace_field_or_constant" in self.errors: + self.errors["leading_whitespace_field_or_constant"] = [] + self.errors["leading_whitespace_field_or_constant"].append(error) + + # Now we can parse the stripped line + fieldOrConstant = line.strip() + + # Check that the field or constant has only single whitespace separators + stripped_fieldOrConstant = re.sub(r'\s+', ' ', fieldOrConstant) # Collapse all spaces to a single space (LHS already stripped). + if stripped_fieldOrConstant != fieldOrConstant: + #print("Field/Constant has multiple whitespace characters") # Since the collapsed version shows them. + error = Error("field_or_constant_has_multiple_whitepsace", self.filename, line_number, line) + if not "field_or_constant_has_multiple_whitepsace" in self.errors: + self.errors["field_or_constant_has_multiple_whitepsace"] = [] + self.errors["field_or_constant_has_multiple_whitepsace"].append(error) + + fieldOrConstant = stripped_fieldOrConstant + + + + comment = None + if "#" in line: + commentExtract = line.split("#", 1) # Split once on left-most '#' + fieldOrConstant = commentExtract[0].strip() + comment = commentExtract[-1].strip() + + if "=" not in fieldOrConstant: + # Is a field: + field = fieldOrConstant.split(" ") + type = field[0].strip() + name = field[1].strip() + field = MessageField(name, type, comment, line_number, parentMessage) + self.fields.append(field) + else: + temp = fieldOrConstant.split("=") + value = temp[-1] + typeAndName = temp[0].split(" ") + type = typeAndName[0] + name = typeAndName[1] + if name.startswith("VEHICLE_CMD_") and parentMessage.name == 'VehicleCommand': #it's a command. + #print(f"DEBUG: startswith VEHICLE_CMD_ {name}") + commandConstant = CommandConstant(name, type, value, comment, line_number, parentMessage) + #commandConstant.display_info() + self.commandConstants[name]=commandConstant + else: #it's a constant (or part of an enum) + constantField = ConstantValue(name, type, value, comment, line_number) + self.constantFields[name]=constantField + + + def parseFile(self): + initial_block_lines = [] + #stopping_token = None + found_first_relevant_content = False + gettingInitialComments = False + gettingFields = False + + with open(self.msg_filename, 'r', encoding='utf-8') as uorbfile: + lines = uorbfile.read().splitlines() + for line_number, line in enumerate(lines, 1): + + if line != line.rstrip(): + #print(f"[{self.filename}] Trailing whitespace on line {line_number}: XX{line}YY") + error = Error("trailing_whitespace", self.filename, line_number, line) + if not "trailing_whitespace" in self.errors: + self.errors["trailing_whitespace"] = [] + self.errors["trailing_whitespace"].append(error) + + #print(f"line: {line}") + stripped_line = re.sub(r'\s+', ' ', line).strip() # Collapse all spaces to a single space and strip stuff off end. + #print(f"stripped_line: {stripped_line}") + # TODO? Perhaps report whitespace if the size of those two is different and it is empty + # Or perhaps we just fix it on request + + isEmptyLine = False if line.strip() else True + if not found_first_relevant_content and isEmptyLine: #Empty line + #print(f"{self.filename}: Empty line at start of file: [{line_number}]\n {line}") + error = Error("empty_start_line", self.filename, line_number, line) + if not "empty_start_line" in self.errors: + self.errors["empty_start_line"] = [] + self.errors["empty_start_line"].append(error) + #error.display_error() + continue + if not found_first_relevant_content and not isEmptyLine: + found_first_relevant_content = True + + if stripped_line.startswith("#"): + gettingInitialComments = True + else: + gettingInitialComments = False + gettingFields = True + + if gettingInitialComments and stripped_line.startswith("#"): + stripped_line=stripped_line[1:].strip() + #print(f"DEBUG: gettingInitialComments: comment line: {stripped_line}") + initial_block_lines.append(stripped_line) + else: + gettingInitialComments = False + gettingFields = True #Getting fields and constants + if gettingFields: + if isEmptyLine: + continue # empty line + if stripped_line.startswith("# TOPICS "): + stripped_line = stripped_line[9:] + stripped_line = stripped_line.split(" ") + self.topics+= stripped_line + # Note, default topic and topic errors handled after all lines parsed + continue + if stripped_line.startswith("#"): + # Its an internal comment + stripped_line=stripped_line[1:].strip() + + if stripped_line: + #print(f"{self.filename}: Internal comment: [{line_number}]\n {line}") + error = Error("internal_comment", self.filename, line_number, line) + if not "internal_comment" in self.errors: + self.errors["internal_comment"] = [] + self.errors["internal_comment"].append(error) + else: + #print(f"{self.filename}: Empty internal comment: [{line_number}]\n {line}") + error = Error("internal_comment_empty", self.filename, line_number, line) + if not "internal_comment_empty" in self.errors: + self.errors["internal_comment_empty"] = [] + self.errors["internal_comment_empty"].append(error) + #pass # Empty comment + continue + + # Must be a field or a comment. + self.handleField(line, line_number, parentMessage=self) + + # Fix up topics if the topic is empty + def camel_to_snake(name): + # Match upper case not at start of string + s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) + # Handle cases with multiple capital first letter + return re.sub('([A-Z]+)([A-Z][a-z]*)', r'\1_\2', s1).lower() + + defaultTopic = camel_to_snake(self.name) + if len(self.topics) == 0: + # We have no topic declared, so set the default topic + self.topics.append(defaultTopic) + elif len(self.topics) == 1: + # We have 1 topic declared - either it is default or there is some issue. + if defaultTopic in self.topics: + # Declared topic is default topic + error = Error("topic_error", self.filename, "", f"WARNING: TOPIC {defaultTopic} unnecessarily declared for {self.name}") + else: + # Declared topic is not default topic + error = Error("topic_error", self.filename, "", f"NOTE: TOPIC {self.topics[1]}: Only Declared topic is not default topic {defaultTopic} for {self.name}") + if not "topic_error" in self.errors: + self.errors["topic_error"] = [] + self.errors["topic_error"].append(error) + elif len(self.topics) > 1: + if defaultTopic not in self.topics: + error = Error("topic_error", self.filename, "", f"NOTE: TOPIC - Default topic {defaultTopic} for {self.name} not in {self.topics}") + + # Parse our short and long description + #print(f"DEBUG: initial_block_lines: {initial_block_lines}") + doingLongDescription = False + for summaryline in initial_block_lines: + if not self.shortDescription and summaryline.strip() == '': + continue + if not doingLongDescription and not summaryline.strip() == '': + self.shortDescription += f" {summaryline}" + self.shortDescription = self.shortDescription.strip() + if not self.shortDescription[-1:] == ".": # Add terminating fullstop if not present. + self.shortDescription += "." + if not doingLongDescription and summaryline.strip() == '': + doingLongDescription = True + continue + if doingLongDescription: + self.longDescription += f"{summaryline}\n" + + if self.longDescription: + self.longDescription.strip() + + if not self.shortDescription: + # Summary has not been defined + error = Error("summary_missing", self.filename) + if not "summary_missing" in self.errors: + self.errors["summary_missing"] = [] + self.errors["summary_missing"].append(error) + + + # TODO Parse our constantValues into enums, leaving only constants + constantValuesToRemove = [] + #print(f"DEBUG: Self.enums: {self.enums}") + for enumName, enumObject in self.enums.items(): + for enumValueName, enumValueObject in self.constantFields.items(): + if enumValueName.startswith(enumName): + # Copy this value into the object (cant be duplicate because parent is dict) + enumObject.enumValues[enumValueName]=enumValueObject + constantValuesToRemove.append(enumValueName) + # Now delete the original enumvalues + for enumValName in constantValuesToRemove: + del self.constantFields[enumValName] + constantsNotAssignedToEnums = len(self.constantFields) + if constantsNotAssignedToEnums > 0: + #print(f"Debug: WARNING constantsNotAssignedToEnums: {constantsNotAssignedToEnums}") + for enumValueName, enumValue in self.constantFields.items(): + if enumValueName in ALLOWED_CONSTANTS_NOT_IN_ENUM: # Ignore constants + pass + else: + error = Error("constant_not_in_assigned_enum", self.filename, enumValue.line_number, enumValueName) + if not "constant_not_in_assigned_enum" in self.errors: + self.errors["constant_not_in_assigned_enum"] = [] + self.errors["constant_not_in_assigned_enum"].append(error) + # TODO Maybe present as list of possible enums. import yaml @@ -127,83 +924,50 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description='Generate docs from .msg files') parser.add_argument('-d', dest='dir', help='output directory', required=True) + parser.add_argument('-e', dest='errors', action='store_true', help='Report errors') + parser.add_argument('-m', dest='error_messages', help='Message to report errors against (by default all)') args = parser.parse_args() output_dir = args.dir if not os.path.isdir(output_dir): + print(f"making output_dir {output_dir}") os.mkdir(output_dir) msg_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../msg") msg_files = get_msgs_list(msg_path) + msg_files.sort() versioned_msgs_list = '' unversioned_msgs_list = '' + msgTypes = set() for msg_file in msg_files: + # Add messages to set of allowed types (compound types) + #msg_type = msg_file.rsplit('/')[-1] + #msg_type = msg_type.rsplit('\\')[-1] + #msg_type = msg_type.rsplit('.')[0] msg_name = os.path.splitext(os.path.basename(msg_file))[0] - output_file = os.path.join(output_dir, msg_name+'.md') - msg_filename = os.path.join(msg_path, msg_file) - print("{:} -> {:}".format(msg_filename, output_file)) + msgTypes.add(msg_name) - #Format msg url - msg_url="[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/%s)" % msg_file - - msg_description = "" - summary_description = "" - - #Get msg description (first non-empty comment line from top of msg) - with open(msg_filename, 'r') as lineparser: - line = lineparser.readline() - while line.startswith('#') or (line.strip() == ''): - print('DEBUG: line: %s' % line) - line=line[1:].strip()+'\n' - stripped_line=line.strip() - if msg_description and not summary_description and stripped_line=='': - summary_description = msg_description.strip() - - msg_description+=line - line = lineparser.readline() - msg_description=msg_description.strip() - if not summary_description and msg_description: - summary_description = msg_description - print('msg_description: Z%sZ' % msg_description) - print('summary_description: Z%sZ' % summary_description) - summary_description - msg_contents = "" - #Get msg contents (read the file) - with open(msg_filename, 'r') as source_file: - msg_contents = source_file.read() - - #Format markdown using msg name, comment, url, contents. - markdown_output="""# %s (UORB message) - -%s - -%s - -```c -%s -``` -""" % (msg_name, msg_description, msg_url, msg_contents) - - with open(output_file, 'w') as content_file: - content_file.write(markdown_output) + for msg_file in msg_files: + message = UORBMessage(msg_file) + # Any additional tests that can't be in UORBMessage parser go here. + message.markdown_out() # Categorize as versioned or unversioned if "versioned" in msg_file: - versioned_msgs_list += '- [%s](%s.md)' % (msg_name, msg_name) - if summary_description: - versioned_msgs_list += " — %s" % summary_description + versioned_msgs_list += f"- [{message.name}]({message.name}.md)" + if message.shortDescription: + versioned_msgs_list += f" — {message.shortDescription}" versioned_msgs_list += "\n" else: - unversioned_msgs_list += '- [%s](%s.md)' % (msg_name, msg_name) - if summary_description: - unversioned_msgs_list += " — %s" % summary_description + unversioned_msgs_list += f"- [{message.name}]({message.name}.md)" + if message.shortDescription: + unversioned_msgs_list += f" — {message.shortDescription}" unversioned_msgs_list += "\n" - # Write out the index.md file - index_text="""# uORB Message Reference + index_text=f"""# uORB Message Reference ::: info This list is [auto-generated](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/msg/generate_msg_docs.py) from the source code. @@ -218,14 +982,14 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m ## Versioned Messages -%s +{versioned_msgs_list} ## Unversioned Messages -%s - """ % (versioned_msgs_list, unversioned_msgs_list) +{unversioned_msgs_list} + """ index_file = os.path.join(output_dir, 'index.md') - with open(index_file, 'w') as content_file: + with open(index_file, 'w', encoding='utf-8') as content_file: content_file.write(index_text) generate_dds_yaml_doc(msg_files) diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css index d3862762c0..161b1f383b 100644 --- a/docs/.vitepress/theme/style.css +++ b/docs/.vitepress/theme/style.css @@ -160,3 +160,44 @@ .vp-doc img { display: inline; /* block by default set by vitepress */ } + + +/** + * Custom styles for wide pages + * -------------------------------------------------------------------------- */ + +.is-wide-page .content-container { + max-width: 100% !important; +} +@media (min-width: 1280px) { + .is-wide-page .content { + min-width: 940px !important; + } +} + +/* Make page width larger */ +@media (min-width: 1440px) { + .is-wide-page .VPSidebar { + padding-left: 32px !important; + width: var(--vp-sidebar-width) !important; + } + .is-wide-page .VPContent.has-sidebar { + padding-left: var(--vp-sidebar-width) !important; + padding-right: 0 !important; + } + + .is-wide-page .VPNavBar.has-sidebar .title { + padding-left: 32px !important; + } + + .is-wide-page .VPNavBar.has-sidebar .content { + padding-left: var(--vp-sidebar-width) !important; + padding-right: 32px !important; + } + + /* Very hacky */ + .is-wide-page .VPNavBar.has-sidebar #local-search { + z-index: 10; + } + +} From 271d3f01a389bbf25386e94ed9142cebddeffa51 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 6 Feb 2026 06:17:44 +1100 Subject: [PATCH 36/71] Update mavlink/mavlink to latest[A (#26410) --- src/modules/mavlink/mavlink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/mavlink/mavlink b/src/modules/mavlink/mavlink index d6a7eeaf43..1ba67b3c9c 160000 --- a/src/modules/mavlink/mavlink +++ b/src/modules/mavlink/mavlink @@ -1 +1 @@ -Subproject commit d6a7eeaf43319ce6da19a1973ca40180a4210643 +Subproject commit 1ba67b3c9c46f56a644e6f4e8a4c359172ed14bc From 3eb02559226dd3bf14ce2c9548f02e3a69697d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Thu, 5 Feb 2026 10:15:04 +0100 Subject: [PATCH 37/71] fix commander: do not trigger Hold (delay) when failsafe action is Warn The new unit test failed before and passes with the fix. --- .../commander/failsafe/failsafe_test.cpp | 33 +++++++++++++++++++ src/modules/commander/failsafe/framework.cpp | 1 + 2 files changed, 34 insertions(+) diff --git a/src/modules/commander/failsafe/failsafe_test.cpp b/src/modules/commander/failsafe/failsafe_test.cpp index 2c190c660c..81eba458ae 100644 --- a/src/modules/commander/failsafe/failsafe_test.cpp +++ b/src/modules/commander/failsafe/failsafe_test.cpp @@ -62,6 +62,9 @@ protected: CHECK_FAILSAFE(status_flags, battery_low_remaining_time, ActionOptions(Action::RTL).causedBy(Cause::RemainingFlightTimeLow)); CHECK_FAILSAFE(status_flags, offboard_control_signal_lost, ActionOptions(Action::Hold)); + CHECK_FAILSAFE(status_flags, navigator_failure, ActionOptions(Action::Warn)); + CHECK_FAILSAFE(status_flags, fd_imbalanced_prop, ActionOptions(Action::None)); + _last_state_test = checkFailsafe(_caller_id_test, _last_state_test, status_flags.fd_motor_failure && status_flags.fd_critical_failure, ActionOptions(Action::Terminate).cannotBeDeferred()); } @@ -305,6 +308,36 @@ TEST_F(FailsafeTest, can_takeover_degraded_failsafe) ASSERT_TRUE(failsafe.userTakeoverActive()); } +TEST_F(FailsafeTest, no_delay_for_warn) +{ + // Ensure there is no Hold/delay when the current action is Warn + FailsafeTester failsafe(nullptr); + + FailsafeBase::State state{}; + state.armed = true; + state.user_intended_mode = vehicle_status_s::NAVIGATION_STATE_MANUAL; + state.vehicle_type = vehicle_status_s::VEHICLE_TYPE_ROTARY_WING; + hrt_abstime time = 3847124342; + failsafe_flags_s failsafe_flags{}; + bool user_intended_mode_updated = false; + + uint8_t updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + + // Navigator failure -> Warn + time += 10_ms; + failsafe_flags.navigator_failure = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Warn); + + // Imbalanced props -> Warn (no delay) + time += 5_s; + failsafe_flags.fd_imbalanced_prop = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Warn); +} + TEST_F(FailsafeTest, no_immediate_takeover_when_failsafe_on_mode_switch) { FailsafeTester failsafe(nullptr); diff --git a/src/modules/commander/failsafe/framework.cpp b/src/modules/commander/failsafe/framework.cpp index 19528b59e9..f8e7e29a0e 100644 --- a/src/modules/commander/failsafe/framework.cpp +++ b/src/modules/commander/failsafe/framework.cpp @@ -488,6 +488,7 @@ void FailsafeBase::getSelectedAction(const State &state, const failsafe_flags_s // Check if we should enter delayed Hold const bool action_can_be_delayed = selected_action != Action::None && + selected_action != Action::Warn && selected_action != Action::Disarm && selected_action != Action::Terminate && selected_action != Action::Hold; From 446895fdc0fdb6f8e4a2743dc7873d767a2eafec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Fri, 6 Feb 2026 08:15:59 +0100 Subject: [PATCH 38/71] Revert "failsafe: prevent Hold when no action is taken (#26383)" This reverts commit 40dc011d82f5b79c11718992200e60c8534929ca. Not needed anymore --- src/modules/commander/failsafe/failsafe.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/commander/failsafe/failsafe.cpp b/src/modules/commander/failsafe/failsafe.cpp index 2f5777b69d..b0c19db29b 100644 --- a/src/modules/commander/failsafe/failsafe.cpp +++ b/src/modules/commander/failsafe/failsafe.cpp @@ -422,7 +422,6 @@ FailsafeBase::ActionOptions Failsafe::fromRemainingFlightTimeLowActParam(int par switch (command_after_remaining_flight_time_low(param_value)) { case command_after_remaining_flight_time_low::None: options.action = Action::None; - options.allow_user_takeover = UserTakeoverAllowed::Never; // Execute immediately without delay break; case command_after_remaining_flight_time_low::Warning: @@ -436,7 +435,6 @@ FailsafeBase::ActionOptions Failsafe::fromRemainingFlightTimeLowActParam(int par default: options.action = Action::None; - options.allow_user_takeover = UserTakeoverAllowed::Never; break; } From 7b7233587665c93fb6eb7e68d3d43035293d8af4 Mon Sep 17 00:00:00 2001 From: Silvan Date: Fri, 6 Feb 2026 17:53:34 +0100 Subject: [PATCH 39/71] UI: remove isAdvanced=false for Altitude Cruise Signed-off-by: Silvan --- src/lib/modes/ui.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib/modes/ui.hpp b/src/lib/modes/ui.hpp index e81a3609ad..fe2e5a9689 100644 --- a/src/lib/modes/ui.hpp +++ b/src/lib/modes/ui.hpp @@ -109,8 +109,6 @@ static inline bool isAdvanced(uint8_t nav_state) switch (nav_state) { case vehicle_status_s::NAVIGATION_STATE_ALTCTL: return false; - case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: return false; - case vehicle_status_s::NAVIGATION_STATE_POSCTL: return false; case vehicle_status_s::NAVIGATION_STATE_EXTERNAL1: return false; From a5a7dd802cacff91bf041abc5c7b5e496cf7aa18 Mon Sep 17 00:00:00 2001 From: Aaron1356 Date: Fri, 6 Feb 2026 14:26:13 -0600 Subject: [PATCH 40/71] [Feature] Adding I2C driver for the GRF250 and GRF500 models (#26425) * Adding the GRF I2C driver * I2C Driver Working * Removing a lot of unnecessary code * fixing names * Changing the i2c Driver to be in the lightware laser * remove the old driver * formatting fix * Adding Ligthware GRF to documentation --- docs/en/sensor/sfxx_lidar.md | 2 + .../lightware_laser_i2c.cpp | 64 +++++++++++++++++++ .../lightware_laser_i2c/parameters.c | 4 +- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/docs/en/sensor/sfxx_lidar.md b/docs/en/sensor/sfxx_lidar.md index ccc080107c..d9838ee45e 100644 --- a/docs/en/sensor/sfxx_lidar.md +++ b/docs/en/sensor/sfxx_lidar.md @@ -15,6 +15,8 @@ The following models are supported by PX4, and can be connected to either the I2 | [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | I2C bus | Waterproofed (IP67) with servo for sense-and-avoid applications | | [SF30/D](https://lightwarelidar.com/shop/sf30-d-200-m/) | 200 | I2C bus | Waterproofed (IP67) | | [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | Serial | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| [GRF250](https://lightwarelidar.com/shop/grf-250/) | 250 | I2C | Gimbal Range Finder +| [GRF500](https://lightwarelidar.com/shop/grf-500/) | 500 | I2C | Gimbal Range Finder ::: details Discontinued diff --git a/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp b/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp index 73f637addb..d5e9a8088b 100644 --- a/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp +++ b/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp @@ -107,6 +107,12 @@ private: ZeroOffset = 116, }; + enum class RegisterGRF : uint8_t { + DistanceOutput = 27, + UpdateRate = 74, + }; + + static constexpr uint16_t output_data_config_sf20 = 0b110'1011'0100; static constexpr uint8_t output_data_config_sf30 = 0b0111'1110; @@ -123,6 +129,7 @@ private: Generic = 0, LW20c, SF30d, + GRF, }; enum class State { Configuring, @@ -242,6 +249,20 @@ int LightwareLaser::init() _type = Type::SF30d; break; + case 8: /* GRF250 (250m 5Hz) */ + _px4_rangefinder.set_min_distance(0.1f); + _px4_rangefinder.set_max_distance(250.0f); + _conversion_interval = 200000; + _type = Type::GRF; + break; + + case 9: /* GRF500 (500m 5Hz) */ + _px4_rangefinder.set_min_distance(0.1f); + _px4_rangefinder.set_max_distance(500.0f); + _conversion_interval = 200000; + _type = Type::GRF; + break; + default: PX4_ERR("invalid HW model %" PRId32 ".", hw_model); return ret; @@ -278,6 +299,9 @@ int LightwareLaser::probe() case Type::SF30d: return enableI2CBinaryProtocol("SF30", "LW30"); + + case Type::GRF: + return enableI2CBinaryProtocol("GRF250", "GRF500"); } return -1; @@ -361,6 +385,17 @@ int LightwareLaser::configure() return ret; } break; + + case Type::GRF: { + int ret = enableI2CBinaryProtocol("GRF250", "GRF500"); + const uint8_t cmd1[] = {(uint8_t) RegisterGRF::UpdateRate, 0, 0, 0, 50}; + ret |= transfer(cmd1, sizeof(cmd1), nullptr, 0); + uint8_t cmd2[] = {(uint8_t)RegisterGRF::DistanceOutput, 0, 0, 1}; + ret |= transfer(cmd2, sizeof(cmd2), nullptr, 0); + + return ret; + } + break; } return -1; @@ -390,6 +425,29 @@ int LightwareLaser::collect() break; } + case Type::GRF: { + + /* read from the sensor */ + perf_begin(_sample_perf); + uint8_t val[4] {}; + const hrt_abstime timestamp_sample = hrt_absolute_time(); + + if (readRegister((uint8_t)Register::DistanceData, &val[0], 4) < 0) { + perf_count(_comms_errors); + perf_end(_sample_perf); + PX4_INFO("Register Read Error"); + return PX4_ERROR; + } + + perf_end(_sample_perf); + + uint16_t distance_cm = val[2] << 16 | val[1] << 8 | val[0]; + float distance_m = float(distance_cm) * 1e-1f; + + _px4_rangefinder.update(timestamp_sample, distance_m); + break; + } + case Type::LW20c: case Type::SF30d: @@ -416,6 +474,8 @@ int LightwareLaser::collect() _px4_rangefinder.update(timestamp_sample, distance_m, quality); break; + + } return PX4_OK; @@ -498,6 +558,10 @@ int LightwareLaser::updateRestriction() const uint8_t cmd[] = {(uint8_t)Register::LaserFiring, (uint8_t)(_restriction ? 0 : 1)}; return transfer(cmd, sizeof(cmd), nullptr, 0); } + + case Type::GRF: { + return 0; + } } } diff --git a/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c b/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c index 40b8264f49..8fa96b629e 100644 --- a/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c +++ b/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c @@ -36,7 +36,7 @@ * * @reboot_required true * @min 0 - * @max 7 + * @max 9 * @group Sensors * @value 0 Disabled * @value 1 SF10/a @@ -46,6 +46,8 @@ * @value 5 SF/LW20/b * @value 6 SF/LW20/c * @value 7 SF/LW30/d + * @value 8 GRF250 + * @value 9 GRF500 */ PARAM_DEFINE_INT32(SENS_EN_SF1XX, 0); From ecb222c7e7b2dc7cb11bbc5f067eeb0e7fab4f41 Mon Sep 17 00:00:00 2001 From: Andrew Brahim <35986980+dirksavage88@users.noreply.github.com> Date: Sun, 8 Feb 2026 22:36:11 -0500 Subject: [PATCH 41/71] uavcannode: implement hardpoint commands (#26334) * implement cannode hardpoint commands Signed-off-by: dirksavage88 * Update src/drivers/uavcannode/Subscribers/HardpointCommand.hpp Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> * Update src/drivers/uavcannode/Subscribers/HardpointCommand.hpp Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> * add hardpoint sub to ark cannode, simplify handling of hardpoint broadcast Signed-off-by: dirksavage88 --------- Signed-off-by: dirksavage88 Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> --- boards/ark/cannode/default.px4board | 1 + src/drivers/uavcannode/Kconfig | 4 + .../Subscribers/HardpointCommand.hpp | 123 ++++++++++++++++++ src/drivers/uavcannode/UavcanNode.cpp | 8 ++ 4 files changed, 136 insertions(+) create mode 100644 src/drivers/uavcannode/Subscribers/HardpointCommand.hpp diff --git a/boards/ark/cannode/default.px4board b/boards/ark/cannode/default.px4board index 29b964b237..f886a22b2e 100644 --- a/boards/ark/cannode/default.px4board +++ b/boards/ark/cannode/default.px4board @@ -31,6 +31,7 @@ CONFIG_UAVCANNODE_ESC_RAW_COMMAND=y CONFIG_UAVCANNODE_ESC_STATUS=y CONFIG_UAVCANNODE_FLOW_MEASUREMENT=y CONFIG_UAVCANNODE_GNSS_FIX=y +CONFIG_UAVCANNODE_HARDPOINT_COMMAND=y CONFIG_UAVCANNODE_HYGROMETER_MEASUREMENT=y CONFIG_UAVCANNODE_LIGHTS_COMMAND=y CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH=y diff --git a/src/drivers/uavcannode/Kconfig b/src/drivers/uavcannode/Kconfig index 532fe3229d..d0edc5d44b 100644 --- a/src/drivers/uavcannode/Kconfig +++ b/src/drivers/uavcannode/Kconfig @@ -34,6 +34,10 @@ if DRIVERS_UAVCANNODE bool "Include GNSS fix" default n + config UAVCANNODE_HARDPOINT_COMMAND + bool "Include hardpoint commands" + default n + config UAVCANNODE_HYGROMETER_MEASUREMENT bool "Include hygrometer measurement" default n diff --git a/src/drivers/uavcannode/Subscribers/HardpointCommand.hpp b/src/drivers/uavcannode/Subscribers/HardpointCommand.hpp new file mode 100644 index 0000000000..87aba37593 --- /dev/null +++ b/src/drivers/uavcannode/Subscribers/HardpointCommand.hpp @@ -0,0 +1,123 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include "UavcanSubscriberBase.hpp" + +#include + +#include +#include + +namespace uavcannode +{ + +class HardpointCommand; + +typedef uavcan::MethodBinder&)> + HardpointCommandBinder; + +class HardpointCommand : + public UavcanSubscriberBase, + private uavcan::Subscriber +{ +public: + HardpointCommand(uavcan::INode &node) : + UavcanSubscriberBase(uavcan::equipment::hardpoint::Command::DefaultDataTypeID), + uavcan::Subscriber(node) + {} + + bool init() + { + if (start(HardpointCommandBinder(this, &HardpointCommand::callback)) < 0) { + PX4_ERR("uavcan::equipment::hardpoint::Command subscription failed"); + return false; + } + + return true; + } + + void PrintInfo() const override + { + printf("\t%s:%d -> %s\n", + uavcan::equipment::hardpoint::Command::getDataTypeFullName(), + uavcan::equipment::hardpoint::Command::DefaultDataTypeID, + _actuator_servos_pub.get_topic()->o_name); + } + +private: + void callback(const uavcan::ReceivedDataStructure &msg) + { + + uint8_t servo_id = msg.hardpoint_id; + actuator_servos_s actuator_servos {}; + + if (servo_id >= actuator_servos_s::NUM_CONTROLS) { + return; + } + + for (uint8_t i = servo_id; i < actuator_servos_s::NUM_CONTROLS; ++i) { + + actuator_servos.timestamp = hrt_absolute_time(); + actuator_servos.timestamp_sample = actuator_servos.timestamp; + + if (msg.command == 1) { + actuator_servos.control[i] = 1; // grip + + } else if (msg.command == 0) { + actuator_servos.control[i] = -1; // release + + } else { + actuator_servos.control[i] = 0; // do nothing + } + + actuator_servos.timestamp = hrt_absolute_time(); + actuator_servos.timestamp_sample = actuator_servos.timestamp; + + // If ID is not 0 (broadcast), do not iterate + if (servo_id != 0) { + break; + } + + } + + _actuator_servos_pub.publish(actuator_servos); + + } + + uORB::Publication _actuator_servos_pub{ORB_ID(actuator_servos)}; + +}; +} // namespace uavcannode diff --git a/src/drivers/uavcannode/UavcanNode.cpp b/src/drivers/uavcannode/UavcanNode.cpp index 6d0799fc27..0940791c90 100644 --- a/src/drivers/uavcannode/UavcanNode.cpp +++ b/src/drivers/uavcannode/UavcanNode.cpp @@ -121,6 +121,10 @@ #include "Subscribers/ServoArrayCommand.hpp" #endif // CONFIG_UAVCANNODE_SERVO_ARRAY_COMMAND +#if defined(CONFIG_UAVCANNODE_HARDPOINT_COMMAND) +#include "Subscribers/HardpointCommand.hpp" +#endif // CONFIG_UAVCANNODE_HARDPOINT_COMMAND + using namespace time_literals; namespace uavcannode @@ -485,6 +489,10 @@ int UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events _subscriber_list.add(new ServoArrayCommand(_node)); #endif // CONFIG_UAVCANNODE_SERVO_ARRAY_COMMAND +#if defined(CONFIG_UAVCANNODE_HARDPOINT_COMMAND) + _subscriber_list.add(new HardpointCommand(_node)); +#endif // CONFIG_UAVCANNODE_HARDPOINT_COMMAND + for (auto &subscriber : _subscriber_list) { subscriber->init(); } From 5e54d727fc8eecfc578fbf0d2e791aa075ebb102 Mon Sep 17 00:00:00 2001 From: Eric Katzfey Date: Tue, 4 Mar 2025 13:50:45 -0800 Subject: [PATCH 42/71] voxl_esc: Limit frequency of UART passthru writes to 20Hz --- src/drivers/actuators/voxl_esc/voxl_esc.cpp | 22 +++++++++++++-------- src/drivers/actuators/voxl_esc/voxl_esc.hpp | 1 + 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/drivers/actuators/voxl_esc/voxl_esc.cpp b/src/drivers/actuators/voxl_esc/voxl_esc.cpp index ec4db9e2d4..099a552a26 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc.cpp +++ b/src/drivers/actuators/voxl_esc/voxl_esc.cpp @@ -1336,16 +1336,22 @@ bool VoxlEsc::updateOutputs(uint16_t outputs[MAX_ACTUATORS], uint8_t num_writes = 0; - while (_esc_serial_passthru_sub.updated() && (num_writes < 4)) { - mavlink_tunnel_s uart_passthru{}; - _esc_serial_passthru_sub.copy(&uart_passthru); + // Don't do these faster than 20Hz + if (hrt_elapsed_time(&_last_uart_passthru) > 50_ms) { + _last_uart_passthru = hrt_absolute_time(); - if (_uart_port.write(uart_passthru.payload, uart_passthru.payload_length) != uart_passthru.payload_length) { - PX4_ERR("Failed to send mavlink tunnel data to esc"); - return false; + // Don't do more than a few writes each check + while (_esc_serial_passthru_sub.updated() && (num_writes < 4)) { + mavlink_tunnel_s uart_passthru{}; + _esc_serial_passthru_sub.copy(&uart_passthru); + + if (_uart_port.write(uart_passthru.payload, uart_passthru.payload_length) != uart_passthru.payload_length) { + PX4_ERR("Failed to send mavlink tunnel data to esc"); + return false; + } + + num_writes++; } - - num_writes++; } perf_count(_output_update_perf); diff --git a/src/drivers/actuators/voxl_esc/voxl_esc.hpp b/src/drivers/actuators/voxl_esc/voxl_esc.hpp index c5885b20d7..ee8b931f07 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc.hpp +++ b/src/drivers/actuators/voxl_esc/voxl_esc.hpp @@ -257,6 +257,7 @@ private: Battery _battery; static constexpr unsigned _battery_report_interval{100_ms}; hrt_abstime _last_battery_report_time; + hrt_abstime _last_uart_passthru{0}; bool _device_initialized{false}; From eb43d2173053849a4c35ec2270f092fc424d3bb6 Mon Sep 17 00:00:00 2001 From: Eric Katzfey Date: Tue, 4 Mar 2025 13:52:52 -0800 Subject: [PATCH 43/71] voxl2_io: Added UART passthru --- msg/MavlinkTunnel.msg | 2 +- src/drivers/voxl2_io/voxl2_io.cpp | 32 ++++++++++++++++++++++++ src/drivers/voxl2_io/voxl2_io.hpp | 4 +++ src/modules/mavlink/mavlink_receiver.cpp | 4 +++ src/modules/mavlink/mavlink_receiver.h | 1 + 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/msg/MavlinkTunnel.msg b/msg/MavlinkTunnel.msg index 140bca5a1b..bc9949f139 100644 --- a/msg/MavlinkTunnel.msg +++ b/msg/MavlinkTunnel.msg @@ -20,4 +20,4 @@ uint8 payload_length # Length of the data transported in payload uint8[128] payload # Data itself # Topic aliases for known payload types -# TOPICS mavlink_tunnel esc_serial_passthru +# TOPICS mavlink_tunnel esc_serial_passthru io_serial_passthru diff --git a/src/drivers/voxl2_io/voxl2_io.cpp b/src/drivers/voxl2_io/voxl2_io.cpp index 66551e468a..07b29ce7d4 100644 --- a/src/drivers/voxl2_io/voxl2_io.cpp +++ b/src/drivers/voxl2_io/voxl2_io.cpp @@ -276,6 +276,31 @@ int Voxl2IO::get_version_info() return (got_response == true ? 0 : -1); } +int Voxl2IO::handle_uart_passthru() +{ + int num_writes = 0; + + // Don't do these faster than 20Hz + if (hrt_elapsed_time(&_last_uart_passthru) > 50_ms) { + _last_uart_passthru = hrt_absolute_time(); + + // Don't do more than a few writes each check + while (_io_serial_passthru_sub.updated() && (num_writes < 4)) { + mavlink_tunnel_s uart_passthru{}; + _io_serial_passthru_sub.copy(&uart_passthru); + + if (_uart_port.write(uart_passthru.payload, uart_passthru.payload_length) != uart_passthru.payload_length) { + PX4_ERR("Failed to send mavlink tunnel data"); + return false; + } + + num_writes++; + } + } + + return num_writes; +} + bool Voxl2IO::updateOutputs(uint16_t outputs[input_rc_s::RC_INPUT_MAX_CHANNELS], unsigned num_outputs, unsigned num_control_groups_updated) { @@ -561,6 +586,13 @@ void Voxl2IO::Run() /* check at end of cycle (updateSubscriptions() can potentially change to a different WorkQueue thread) */ _mixing_output.updateSubscriptions(true); + + int num_writes = handle_uart_passthru(); + + if (_debug && num_writes) { + PX4_INFO("UART Passthru wrote %d packets", num_writes); + } + perf_end(_cycle_perf); } diff --git a/src/drivers/voxl2_io/voxl2_io.hpp b/src/drivers/voxl2_io/voxl2_io.hpp index 31f9cac9da..1f9c6c2eaa 100644 --- a/src/drivers/voxl2_io/voxl2_io.hpp +++ b/src/drivers/voxl2_io/voxl2_io.hpp @@ -55,6 +55,7 @@ #include #include #include +#include #include "voxl2_io_packet.h" #include "voxl2_io_packet_types.h" @@ -188,9 +189,11 @@ private: /* Subscriptions */ uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)}; + uORB::Subscription _io_serial_passthru_sub{ORB_ID(io_serial_passthru)}; bool _pwm_on{false}; bool _outputs_disabled{false}; + hrt_abstime _last_uart_passthru{0}; perf_counter_t _cycle_perf; perf_counter_t _output_update_perf; @@ -208,4 +211,5 @@ private: int update_params(); int calibrate_escs(); std::string board_id_to_name(int board_id); + int handle_uart_passthru(); }; diff --git a/src/modules/mavlink/mavlink_receiver.cpp b/src/modules/mavlink/mavlink_receiver.cpp index 6143c0a0dd..d34074cba2 100644 --- a/src/modules/mavlink/mavlink_receiver.cpp +++ b/src/modules/mavlink/mavlink_receiver.cpp @@ -1989,6 +1989,10 @@ MavlinkReceiver::handle_message_tunnel(mavlink_message_t *msg) _esc_serial_passthru_pub.publish(tunnel); break; + case MAV_TUNNEL_PAYLOAD_TYPE_MODALAI_IO_UART_PASSTHRU: + _io_serial_passthru_pub.publish(tunnel); + break; + default: _mavlink_tunnel_pub.publish(tunnel); break; diff --git a/src/modules/mavlink/mavlink_receiver.h b/src/modules/mavlink/mavlink_receiver.h index d1c477e1c7..5023c7a7df 100644 --- a/src/modules/mavlink/mavlink_receiver.h +++ b/src/modules/mavlink/mavlink_receiver.h @@ -310,6 +310,7 @@ private: uORB::Publication _log_message_pub{ORB_ID(log_message)}; uORB::Publication _mavlink_tunnel_pub{ORB_ID(mavlink_tunnel)}; uORB::Publication _esc_serial_passthru_pub{ORB_ID(esc_serial_passthru)}; + uORB::Publication _io_serial_passthru_pub{ORB_ID(io_serial_passthru)}; uORB::Publication _obstacle_distance_pub{ORB_ID(obstacle_distance)}; uORB::Publication _offboard_control_mode_pub{ORB_ID(offboard_control_mode)}; uORB::Publication _onboard_computer_status_pub{ORB_ID(onboard_computer_status)}; From 8115cf2597d41d54cb7e0c837dcc8840222c83bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Thu, 5 Feb 2026 11:02:41 +0100 Subject: [PATCH 44/71] docs: update link for px4 ros2 interface lib python api docs --- docs/en/ros2/px4_ros2_control_interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/ros2/px4_ros2_control_interface.md b/docs/en/ros2/px4_ros2_control_interface.md index b07a061ee9..6032e6d2d5 100644 --- a/docs/en/ros2/px4_ros2_control_interface.md +++ b/docs/en/ros2/px4_ros2_control_interface.md @@ -27,7 +27,7 @@ Unless the mode is safety-critical, requires strict timing or very high update r ::: tip If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). -Not all classes have Python bindings yet — the [supported bindings are here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_py/src/px4_ros2). +Not all classes have Python bindings yet — the [supported bindings are here](https://auterion.github.io/px4-ros2-interface-lib/python/index.html). You are welcome to add and contribute missing classes. ::: From 61c990c5ee221e552642eaecbd24253cffb8f890 Mon Sep 17 00:00:00 2001 From: Matthias Grob Date: Mon, 26 Jan 2026 16:26:25 +0100 Subject: [PATCH 45/71] estimator_interface: remove unused getter --- src/modules/ekf2/EKF/estimator_interface.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/modules/ekf2/EKF/estimator_interface.h b/src/modules/ekf2/EKF/estimator_interface.h index e67c558410..f7f6e559c9 100644 --- a/src/modules/ekf2/EKF/estimator_interface.h +++ b/src/modules/ekf2/EKF/estimator_interface.h @@ -190,9 +190,6 @@ public: // return true if the attitude is usable bool attitude_valid() const { return _control_status.flags.tilt_align; } - // get vehicle landed status data - bool get_in_air_status() const { return _control_status.flags.in_air; } - #if defined(CONFIG_EKF2_WIND) bool get_wind_status() const { return _control_status.flags.wind || _external_wind_init; } #endif // CONFIG_EKF2_WIND From f9cdd095b8955ddcd1a1301caf0d7c78fc7e9892 Mon Sep 17 00:00:00 2001 From: Matthias Grob Date: Mon, 26 Jan 2026 16:28:39 +0100 Subject: [PATCH 46/71] gnss_checks: always run strict checks on ground With the goal to never take off if the GNSS solution is not fullfilling the configured requirements still not stopping to use it in case it degrades mid air. --- src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp index 4dbb08bc2d..e9077e8bdd 100644 --- a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp +++ b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp @@ -49,6 +49,11 @@ bool GnssChecks::run(const gnssSample &gnss, uint64_t time_us) bool passed = false; + // Run strict checks while not flying yet + if (!_control_status.flags.in_air) { + _initial_checks_passed = false; + } + if (_initial_checks_passed) { if (runSimplifiedChecks(gnss)) { _time_last_pass_us = time_us; From c4535683a760033716abec776901331959258d7b Mon Sep 17 00:00:00 2001 From: Marco Hauswirth Date: Fri, 6 Feb 2026 11:43:05 +0100 Subject: [PATCH 47/71] ekf2 unit-tests: adapt to strict GNSS checks on ground --- src/modules/ekf2/test/test_EKF_gnss_yaw.cpp | 3 ++- src/modules/ekf2/test/test_EKF_gps.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp b/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp index 93dd222375..665fa8e8c9 100644 --- a/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp +++ b/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp @@ -281,7 +281,8 @@ TEST_F(EkfGpsHeadingTest, yawJmpOnGround) EXPECT_EQ(_ekf_wrapper.getQuaternionResetCounter(), initial_quat_reset_counter + 1); // AND THEN: restart GNSS yaw fusion - _sensor_simulator.runSeconds(5); + // The strict checks on ground require min_health_time_us (10s) to pass again. + _sensor_simulator.runSeconds(11); EXPECT_TRUE(_ekf_wrapper.isIntendingGpsHeadingFusion()); EXPECT_EQ(_ekf_wrapper.getQuaternionResetCounter(), initial_quat_reset_counter + 2); EXPECT_LT(fabsf(matrix::wrap_pi(_ekf_wrapper.getYawAngle() - gps_heading)), math::radians(1.f)); diff --git a/src/modules/ekf2/test/test_EKF_gps.cpp b/src/modules/ekf2/test/test_EKF_gps.cpp index debfec6560..ebd024e363 100644 --- a/src/modules/ekf2/test/test_EKF_gps.cpp +++ b/src/modules/ekf2/test/test_EKF_gps.cpp @@ -81,6 +81,10 @@ TEST_F(EkfGpsTest, gpsTimeout) // GIVEN:EKF that fuses GPS EXPECT_TRUE(_ekf_wrapper.isIntendingGpsFusion()); + // In air the simplified checks are used which do not include satellite count + _ekf->set_in_air_status(true); + _ekf->set_vehicle_at_rest(false); + // WHEN: the number of satellites drops below the minimum _sensor_simulator._gps.setNumberOfSatellites(3); @@ -174,7 +178,7 @@ TEST_F(EkfGpsTest, resetToGpsPosition) const Vector3f simulated_position_change(20.0f, -1.0f, 0.f); _sensor_simulator._gps.stepHorizontalPositionByMeters( Vector2f(simulated_position_change)); - _sensor_simulator.runSeconds(6); + _sensor_simulator.runSeconds(11); // THEN: a reset to the new GPS position should be done const Vector3f estimated_position = _ekf->getPosition(); From f5a56ae42f5c730849bcb520798db8545e5a45cb Mon Sep 17 00:00:00 2001 From: Matthias Grob Date: Tue, 16 Dec 2025 16:26:28 +0100 Subject: [PATCH 48/71] escCheck: rework online check to properly report offline ESCs previous to this 09d79b221f274523349a029e63ab4462e41d0c1c set `esc_online_flags` e.g. for UAVCAN ESCs which specific one is online and that then got compared to a mask where the first `esc_count` bits were set. So if only ESC 5 is mapped and online you get the message "ESC 156 offline" because `esc_online_flags = 0b1000` gets compared to `online_bitmask = 0b1` based on `esc_count = 1` and the motor index is `esc[0].actuator_function = 0` wrapped using `0 - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1 + 1 = 156`. --- .../HealthAndArmingChecks/checks/escCheck.cpp | 49 +++++++++---------- .../HealthAndArmingChecks/checks/escCheck.hpp | 2 +- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp index 9b35c80992..7bc47dc855 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp @@ -82,7 +82,7 @@ void EscChecks::checkAndReport(const Context &context, Report &reporter) checkEscStatus(context, reporter, esc_status); reporter.setIsPresent(health_component_t::motors_escs); - } else if (_param_escs_checks_required.get() + } else if (_param_com_arm_chk_escs.get() && now - _start_time > 5_s) { // Wait a bit after startup to allow esc's to init /* EVENT @@ -102,40 +102,37 @@ void EscChecks::checkAndReport(const Context &context, Report &reporter) void EscChecks::checkEscStatus(const Context &context, Report &reporter, const esc_status_s &esc_status) { - const NavModes required_modes = _param_escs_checks_required.get() ? NavModes::All : NavModes::None; + const NavModes required_modes = _param_com_arm_chk_escs.get() ? NavModes::All : NavModes::None; if (esc_status.esc_count > 0) { - + // Check if one or more the ESCs are offline char esc_fail_msg[50]; esc_fail_msg[0] = '\0'; - int online_bitmask = (1 << esc_status.esc_count) - 1; + for (int i = 0; i < esc_status_s::CONNECTED_ESC_MAX; ++i) { + const bool mapped = math::isInRange(esc_status.esc[i].actuator_function, actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1, + uint8_t(actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1 + actuator_motors_s::NUM_CONTROLS - 1)); + const bool offline = (esc_status.esc_online_flags & (1 << i)) == 0; - // Check if one or more the ESCs are offline - if (online_bitmask != esc_status.esc_online_flags) { - - for (int index = 0; index < esc_status.esc_count; index++) { - if ((esc_status.esc_online_flags & (1 << index)) == 0) { - uint8_t motor_index = esc_status.esc[index].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1 + 1; - /* EVENT - * @description - * - * This check can be configured via COM_ARM_CHK_ESCS parameter. - * - */ - reporter.healthFailure(required_modes, health_component_t::motors_escs, events::ID("check_escs_offline"), - events::Log::Critical, "ESC {1} offline", motor_index); - snprintf(esc_fail_msg + strlen(esc_fail_msg), sizeof(esc_fail_msg) - strlen(esc_fail_msg), "ESC%d ", motor_index); - esc_fail_msg[sizeof(esc_fail_msg) - 1] = '\0'; - } - } - - if (reporter.mavlink_log_pub()) { - mavlink_log_critical(reporter.mavlink_log_pub(), "%soffline. %s\t", esc_fail_msg, context.isArmed() ? "Land now!" : ""); + if (mapped && offline) { + /* EVENT + * @description + * + * This check can be configured via COM_ARM_CHK_ESCS parameter. + * + */ + reporter.healthFailure(required_modes, health_component_t::motors_escs, events::ID("check_escs_offline"), + events::Log::Critical, "ESC {1} offline", i + 1); + snprintf(esc_fail_msg + strlen(esc_fail_msg), sizeof(esc_fail_msg) - strlen(esc_fail_msg), "ESC%d ", i + 1); + esc_fail_msg[sizeof(esc_fail_msg) - 1] = '\0'; } } - for (int index = 0; index < esc_status.esc_count; index++) { + if ((esc_fail_msg[0] != '\0') && reporter.mavlink_log_pub()) { + mavlink_log_critical(reporter.mavlink_log_pub(), "%soffline. %s\t", esc_fail_msg, context.isArmed() ? "Land now!" : ""); + } + + for (int index = 0; index < math::min(esc_status.esc_count, esc_status_s::CONNECTED_ESC_MAX); ++index) { if (esc_status.esc[index].failures != 0) { diff --git a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp index 7e32563e46..a96c147234 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp @@ -54,6 +54,6 @@ private: const hrt_abstime _start_time{hrt_absolute_time()}; DEFINE_PARAMETERS_CUSTOM_PARENT(HealthAndArmingCheckBase, - (ParamBool) _param_escs_checks_required + (ParamBool) _param_com_arm_chk_escs ) }; From b4b1b44c6a7b7e147ce996f726f32be8703021cc Mon Sep 17 00:00:00 2001 From: Matthias Grob Date: Mon, 15 Dec 2025 11:41:12 +0100 Subject: [PATCH 49/71] FailureDetector: consistent timestamp naming --- .../failure_detector/FailureDetector.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/modules/commander/failure_detector/FailureDetector.cpp b/src/modules/commander/failure_detector/FailureDetector.cpp index 0c93f303a7..ee62ade96a 100644 --- a/src/modules/commander/failure_detector/FailureDetector.cpp +++ b/src/modules/commander/failure_detector/FailureDetector.cpp @@ -141,13 +141,13 @@ void FailureDetector::updateAttitudeStatus(const vehicle_status_s &vehicle_statu const bool roll_status = (max_roll > FLT_EPSILON) && (fabsf(roll) > max_roll); const bool pitch_status = (max_pitch > FLT_EPSILON) && (fabsf(pitch) > max_pitch); - hrt_abstime time_now = hrt_absolute_time(); + hrt_abstime now = hrt_absolute_time(); // Update hysteresis _roll_failure_hysteresis.set_hysteresis_time_from(false, (hrt_abstime)(1_s * _param_fd_fail_r_ttri.get())); _pitch_failure_hysteresis.set_hysteresis_time_from(false, (hrt_abstime)(1_s * _param_fd_fail_p_ttri.get())); - _roll_failure_hysteresis.set_state_and_update(roll_status, time_now); - _pitch_failure_hysteresis.set_state_and_update(pitch_status, time_now); + _roll_failure_hysteresis.set_state_and_update(roll_status, now); + _pitch_failure_hysteresis.set_state_and_update(pitch_status, now); // Update status _failure_detector_status.flags.roll = _roll_failure_hysteresis.get_state(); @@ -164,11 +164,9 @@ void FailureDetector::updateExternalAtsStatus() uint32_t pulse_width = pwm_input.pulse_width; bool ats_trigger_status = (pulse_width >= (uint32_t)_param_fd_ext_ats_trig.get()) && (pulse_width < 3_ms); - hrt_abstime time_now = hrt_absolute_time(); - // Update hysteresis _ext_ats_failure_hysteresis.set_hysteresis_time_from(false, 100_ms); // 5 consecutive pulses at 50hz - _ext_ats_failure_hysteresis.set_state_and_update(ats_trigger_status, time_now); + _ext_ats_failure_hysteresis.set_state_and_update(ats_trigger_status, hrt_absolute_time()); _failure_detector_status.flags.ext = _ext_ats_failure_hysteresis.get_state(); } @@ -176,7 +174,7 @@ void FailureDetector::updateExternalAtsStatus() void FailureDetector::updateEscsStatus(const vehicle_status_s &vehicle_status, const esc_status_s &esc_status) { - hrt_abstime time_now = hrt_absolute_time(); + hrt_abstime now = hrt_absolute_time(); if (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) { const int limited_esc_count = math::min(esc_status.esc_count, esc_status_s::CONNECTED_ESC_MAX); @@ -190,7 +188,7 @@ void FailureDetector::updateEscsStatus(const vehicle_status_s &vehicle_status, c } _esc_failure_hysteresis.set_hysteresis_time_from(false, 300_ms); - _esc_failure_hysteresis.set_state_and_update(is_esc_failure, time_now); + _esc_failure_hysteresis.set_state_and_update(is_esc_failure, now); if (_esc_failure_hysteresis.get_state()) { _failure_detector_status.flags.arm_escs = true; @@ -198,7 +196,7 @@ void FailureDetector::updateEscsStatus(const vehicle_status_s &vehicle_status, c } else { // reset ESC bitfield - _esc_failure_hysteresis.set_state_and_update(false, time_now); + _esc_failure_hysteresis.set_state_and_update(false, now); _failure_detector_status.flags.arm_escs = false; } } From f8329ff80dfa38f9c42b7b9f7edf729cf8f4bf57 Mon Sep 17 00:00:00 2001 From: Matthias Grob Date: Tue, 16 Dec 2025 14:24:55 +0100 Subject: [PATCH 50/71] FailureDetector: rework motor status check --- .../failure_detector/FailureDetector.cpp | 118 ++++++------------ .../failure_detector/FailureDetector.hpp | 8 +- 2 files changed, 43 insertions(+), 83 deletions(-) diff --git a/src/modules/commander/failure_detector/FailureDetector.cpp b/src/modules/commander/failure_detector/FailureDetector.cpp index ee62ade96a..7b74a1b869 100644 --- a/src/modules/commander/failure_detector/FailureDetector.cpp +++ b/src/modules/commander/failure_detector/FailureDetector.cpp @@ -101,7 +101,7 @@ void FailureDetector::publishStatus() failure_detector_status.fd_imbalanced_prop = _failure_detector_status.flags.imbalanced_prop; failure_detector_status.fd_motor = _failure_detector_status.flags.motor; failure_detector_status.imbalanced_prop_metric = _imbalanced_prop_lpf.getState(); - failure_detector_status.motor_failure_mask = _motor_failure_esc_timed_out_mask | _motor_failure_esc_under_current_mask; + failure_detector_status.motor_failure_mask = _motor_failure_mask; failure_detector_status.motor_stop_mask = _failure_injector.getMotorStopMask(); failure_detector_status.timestamp = hrt_absolute_time(); _failure_detector_status_pub.publish(failure_detector_status); @@ -261,110 +261,72 @@ void FailureDetector::updateImbalancedPropStatus() void FailureDetector::updateMotorStatus(const vehicle_status_s &vehicle_status, const esc_status_s &esc_status) { - // What need to be checked: - // - // 1. ESC telemetry disappears completely -> dead ESC or power loss on that ESC - // 2. ESC failures like overvoltage, overcurrent etc. But DShot driver for example is not populating the field 'esc_report.failures' - // 3. Motor current too low. Compare drawn motor current to expected value from a parameter - // -- ESC voltage does not really make sense and is highly dependent on the setup + // 1. Telemetry times out -> communication or power lost on that ESC + // 2. Too low current draw compared to commanded thrust + // Overvoltage, overcurrent do not have checks yet esc_report.failures are handled separately - // First wait for some ESC telemetry that has the required fields. Before that happens, don't check this ESC - // Then check + const hrt_abstime now = hrt_absolute_time(); // Only check while armed if (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) { - const hrt_abstime now = hrt_absolute_time(); - const int limited_esc_count = math::min(esc_status.esc_count, esc_status_s::CONNECTED_ESC_MAX); - - actuator_motors_s actuator_motors{}; + actuator_motors_s actuator_motors{}; // Normalized motor thrust commands before thrust model factor is applied _actuator_motors_sub.copy(&actuator_motors); // Check individual ESC reports - for (int esc_status_idx = 0; esc_status_idx < limited_esc_count; esc_status_idx++) { - - const esc_report_s &cur_esc_report = esc_status.esc[esc_status_idx]; - + for (uint8_t i = 0; i < esc_status_s::CONNECTED_ESC_MAX; ++i) { // Map the esc status index to the actuator function index - const unsigned i_esc = cur_esc_report.actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1; + const uint8_t actuator_function_index = + esc_status.esc[i].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1; - if (i_esc >= actuator_motors_s::NUM_CONTROLS) { + if (actuator_function_index >= actuator_motors_s::NUM_CONTROLS) { + continue; // Invalid mapping + } + + const bool timeout = now > esc_status.esc[i].timestamp + 300_ms; + const float current = esc_status.esc[i].esc_current; + + // First wait for ESC telemetry reporting non-zero current. Before that happens, don't check it. + if (current > FLT_EPSILON) { + _esc_has_reported_current[i] = true; + } + + if (!_esc_has_reported_current[i]) { continue; } - // Check if ESC telemetry was available and valid at some point. This is a prerequisite for the failure detection. - if (!(_motor_failure_esc_valid_current_mask & (1 << i_esc)) && cur_esc_report.esc_current > 0.0f) { - _motor_failure_esc_valid_current_mask |= (1 << i_esc); - } + _motor_failure_mask &= ~(1u << actuator_function_index); // Reset bit in mask to be able to accumulate failures + _motor_failure_mask |= (static_cast(timeout) << actuator_function_index); // Telemetry timeout - // Check for telemetry timeout - const bool esc_timed_out = now > cur_esc_report.timestamp + 300_ms; - const bool esc_was_valid = _motor_failure_esc_valid_current_mask & (1 << i_esc); - const bool esc_timeout_currently_flagged = _motor_failure_esc_timed_out_mask & (1 << i_esc); + // Current too low + if (_esc_has_reported_current[i]) { + float thrust = 0.f; - if (esc_was_valid && esc_timed_out && !esc_timeout_currently_flagged) { - // Set flag - _motor_failure_esc_timed_out_mask |= (1 << i_esc); - - } else if (!esc_timed_out && esc_timeout_currently_flagged) { - // Reset flag - _motor_failure_esc_timed_out_mask &= ~(1 << i_esc); - } - - // Check if ESC current is too low - if (cur_esc_report.esc_current > FLT_EPSILON) { - _motor_failure_esc_has_current[i_esc] = true; - } - - if (_motor_failure_esc_has_current[i_esc]) { - float esc_throttle = 0.f; - - if (PX4_ISFINITE(actuator_motors.control[i_esc])) { - esc_throttle = fabsf(actuator_motors.control[i_esc]); + if (PX4_ISFINITE(actuator_motors.control[actuator_function_index])) { + // NAN means motor is turned off -> 0 thrust + thrust = fabsf(actuator_motors.control[actuator_function_index]); } - const bool throttle_above_threshold = esc_throttle > _param_fd_act_mot_thr.get(); - const bool current_too_low = cur_esc_report.esc_current < esc_throttle * - _param_fd_act_mot_c2t.get(); + bool thrust_above_threshold = thrust > _param_fd_act_mot_thr.get(); + bool current_too_low = current < thrust * _param_fd_act_mot_c2t.get(); - if (throttle_above_threshold && current_too_low && !esc_timed_out) { - if (_motor_failure_undercurrent_start_time[i_esc] == 0) { - _motor_failure_undercurrent_start_time[i_esc] = now; - } + _esc_undercurrent_hysteresis[i].set_hysteresis_time_from(false, _param_fd_act_mot_tout.get() * 1_ms); - } else { - if (_motor_failure_undercurrent_start_time[i_esc] != 0) { - _motor_failure_undercurrent_start_time[i_esc] = 0; - } + if (!_esc_undercurrent_hysteresis[i].get_state()) { + // Do not clear because a reaction could be to stop the motor and that would be conidered healty again + _esc_undercurrent_hysteresis[i].set_state_and_update(thrust_above_threshold && current_too_low && !timeout, now); } - if (_motor_failure_undercurrent_start_time[i_esc] != 0 - && now > (_motor_failure_undercurrent_start_time[i_esc] + (_param_fd_act_mot_tout.get() * 1_ms)) - && (_motor_failure_esc_under_current_mask & (1 << i_esc)) == 0) { - // Set flag - _motor_failure_esc_under_current_mask |= (1 << i_esc); - - } // else: this flag is never cleared, as the motor is stopped, so throttle < threshold + _motor_failure_mask |= (static_cast(_esc_undercurrent_hysteresis[i].get_state()) << actuator_function_index); } } - bool critical_esc_failure = (_motor_failure_esc_timed_out_mask != 0 || _motor_failure_esc_under_current_mask != 0); - - if (critical_esc_failure && !(_failure_detector_status.flags.motor)) { - // Add motor failure flag to bitfield - _failure_detector_status.flags.motor = true; - - } else if (!critical_esc_failure && _failure_detector_status.flags.motor) { - // Reset motor failure flag - _failure_detector_status.flags.motor = false; - } + _failure_detector_status.flags.motor = (_motor_failure_mask != 0u); } else { // Disarmed - // reset ESC bitfield - for (int i_esc = 0; i_esc < actuator_motors_s::NUM_CONTROLS; i_esc++) { - _motor_failure_undercurrent_start_time[i_esc] = 0; + for (uint8_t i = 0; i < actuator_motors_s::NUM_CONTROLS; ++i) { + _esc_undercurrent_hysteresis[i].set_state_and_update(false, now); } - _motor_failure_esc_under_current_mask = 0; _failure_detector_status.flags.motor = false; } } diff --git a/src/modules/commander/failure_detector/FailureDetector.hpp b/src/modules/commander/failure_detector/FailureDetector.hpp index 78b4861a7a..26ae114abb 100644 --- a/src/modules/commander/failure_detector/FailureDetector.hpp +++ b/src/modules/commander/failure_detector/FailureDetector.hpp @@ -111,11 +111,9 @@ private: hrt_abstime _imu_status_timestamp_prev{0}; // Motor failure check - uint8_t _motor_failure_esc_valid_current_mask{}; // ESC 1-8, true if ESC telemetry was valid at some point - uint8_t _motor_failure_esc_timed_out_mask{}; // ESC telemetry no longer available -> failure - uint8_t _motor_failure_esc_under_current_mask{}; // ESC drawing too little current -> failure - bool _motor_failure_esc_has_current[actuator_motors_s::NUM_CONTROLS] {false}; // true if some ESC had non-zero current (some don't support it) - hrt_abstime _motor_failure_undercurrent_start_time[actuator_motors_s::NUM_CONTROLS] {}; + bool _esc_has_reported_current[esc_status_s::CONNECTED_ESC_MAX] {}; // true if some ESC had non-zero current (some don't support it) + systemlib::Hysteresis _esc_undercurrent_hysteresis[esc_status_s::CONNECTED_ESC_MAX]; + uint16_t _motor_failure_mask = 0; // actuator function indexed uORB::Subscription _vehicle_attitude_sub{ORB_ID(vehicle_attitude)}; uORB::Subscription _esc_status_sub{ORB_ID(esc_status)}; // TODO: multi-instance From 61a8ae80a61e15695e4551f09a4d60ac5f2c4527 Mon Sep 17 00:00:00 2001 From: Matthias Grob Date: Thu, 18 Dec 2025 17:10:51 +0100 Subject: [PATCH 51/71] FailureDetector: implement upper and lower current limit with offset --- .../failure_detector/FailureDetector.cpp | 49 ++++++++++-------- .../failure_detector/FailureDetector.hpp | 7 ++- .../failure_detector_params.c | 50 +++++++++++++++---- 3 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/modules/commander/failure_detector/FailureDetector.cpp b/src/modules/commander/failure_detector/FailureDetector.cpp index 7b74a1b869..b2eed03290 100644 --- a/src/modules/commander/failure_detector/FailureDetector.cpp +++ b/src/modules/commander/failure_detector/FailureDetector.cpp @@ -269,7 +269,7 @@ void FailureDetector::updateMotorStatus(const vehicle_status_s &vehicle_status, // Only check while armed if (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) { - actuator_motors_s actuator_motors{}; // Normalized motor thrust commands before thrust model factor is applied + actuator_motors_s actuator_motors{}; _actuator_motors_sub.copy(&actuator_motors); // Check individual ESC reports @@ -294,30 +294,36 @@ void FailureDetector::updateMotorStatus(const vehicle_status_s &vehicle_status, continue; } - _motor_failure_mask &= ~(1u << actuator_function_index); // Reset bit in mask to be able to accumulate failures + _motor_failure_mask &= ~(1u << actuator_function_index); // Reset bit in mask to accumulate failures again _motor_failure_mask |= (static_cast(timeout) << actuator_function_index); // Telemetry timeout - // Current too low - if (_esc_has_reported_current[i]) { - float thrust = 0.f; + // Current limits + float thrust = 0.f; - if (PX4_ISFINITE(actuator_motors.control[actuator_function_index])) { - // NAN means motor is turned off -> 0 thrust - thrust = fabsf(actuator_motors.control[actuator_function_index]); - } - - bool thrust_above_threshold = thrust > _param_fd_act_mot_thr.get(); - bool current_too_low = current < thrust * _param_fd_act_mot_c2t.get(); - - _esc_undercurrent_hysteresis[i].set_hysteresis_time_from(false, _param_fd_act_mot_tout.get() * 1_ms); - - if (!_esc_undercurrent_hysteresis[i].get_state()) { - // Do not clear because a reaction could be to stop the motor and that would be conidered healty again - _esc_undercurrent_hysteresis[i].set_state_and_update(thrust_above_threshold && current_too_low && !timeout, now); - } - - _motor_failure_mask |= (static_cast(_esc_undercurrent_hysteresis[i].get_state()) << actuator_function_index); + if (PX4_ISFINITE(actuator_motors.control[actuator_function_index])) { + // Normalized motor thrust commands before thrust model factor is applied, NAN means motor is turned off -> 0 thrust + thrust = fabsf(actuator_motors.control[actuator_function_index]); } + + bool thrust_above_threshold = thrust > _param_fd_act_mot_thr.get(); + bool current_too_low = current < (thrust * _param_fd_act_mot_c2t.get()) - _param_fd_act_low_off.get(); + bool current_too_high = current > (thrust * _param_fd_act_mot_c2t.get()) + _param_fd_act_high_off.get(); + + _esc_undercurrent_hysteresis[i].set_hysteresis_time_from(false, _param_fd_act_mot_tout.get() * 1_ms); + _esc_overcurrent_hysteresis[i].set_hysteresis_time_from(false, _param_fd_act_mot_tout.get() * 1_ms); + + if (!_esc_undercurrent_hysteresis[i].get_state()) { + // Do not clear mid operation because a reaction could be to stop the motor and that would be conidered healthy again + _esc_undercurrent_hysteresis[i].set_state_and_update(thrust_above_threshold && current_too_low && !timeout, now); + } + + if (!_esc_overcurrent_hysteresis[i].get_state()) { + // Do not clear mid operation because a reaction could be to stop the motor and that would be conidered healthy again + _esc_overcurrent_hysteresis[i].set_state_and_update(current_too_high && !timeout, now); + } + + _motor_failure_mask |= (static_cast(_esc_undercurrent_hysteresis[i].get_state()) << actuator_function_index); + _motor_failure_mask |= (static_cast(_esc_overcurrent_hysteresis[i].get_state()) << actuator_function_index); } _failure_detector_status.flags.motor = (_motor_failure_mask != 0u); @@ -325,6 +331,7 @@ void FailureDetector::updateMotorStatus(const vehicle_status_s &vehicle_status, } else { // Disarmed for (uint8_t i = 0; i < actuator_motors_s::NUM_CONTROLS; ++i) { _esc_undercurrent_hysteresis[i].set_state_and_update(false, now); + _esc_overcurrent_hysteresis[i].set_state_and_update(false, now); } _failure_detector_status.flags.motor = false; diff --git a/src/modules/commander/failure_detector/FailureDetector.hpp b/src/modules/commander/failure_detector/FailureDetector.hpp index 26ae114abb..26182f4c3c 100644 --- a/src/modules/commander/failure_detector/FailureDetector.hpp +++ b/src/modules/commander/failure_detector/FailureDetector.hpp @@ -111,8 +111,9 @@ private: hrt_abstime _imu_status_timestamp_prev{0}; // Motor failure check - bool _esc_has_reported_current[esc_status_s::CONNECTED_ESC_MAX] {}; // true if some ESC had non-zero current (some don't support it) + bool _esc_has_reported_current[esc_status_s::CONNECTED_ESC_MAX] {}; // true if ESC reported non-zero current before (some never report any) systemlib::Hysteresis _esc_undercurrent_hysteresis[esc_status_s::CONNECTED_ESC_MAX]; + systemlib::Hysteresis _esc_overcurrent_hysteresis[esc_status_s::CONNECTED_ESC_MAX]; uint16_t _motor_failure_mask = 0; // actuator function indexed uORB::Subscription _vehicle_attitude_sub{ORB_ID(vehicle_attitude)}; @@ -140,6 +141,8 @@ private: (ParamBool) _param_fd_act_en, (ParamFloat) _param_fd_act_mot_thr, (ParamFloat) _param_fd_act_mot_c2t, - (ParamInt) _param_fd_act_mot_tout + (ParamInt) _param_fd_act_mot_tout, + (ParamFloat) _param_fd_act_low_off, + (ParamFloat) _param_fd_act_high_off ) }; diff --git a/src/modules/commander/failure_detector/failure_detector_params.c b/src/modules/commander/failure_detector/failure_detector_params.c index e472c304b8..9324820472 100644 --- a/src/modules/commander/failure_detector/failure_detector_params.c +++ b/src/modules/commander/failure_detector/failure_detector_params.c @@ -169,12 +169,13 @@ PARAM_DEFINE_INT32(FD_IMB_PROP_THR, 30); * * @group Failure Detector */ -PARAM_DEFINE_INT32(FD_ACT_EN, 1); +PARAM_DEFINE_INT32(FD_ACT_EN, 0); /** - * Motor Failure Throttle Threshold + * Motor Failure Thrust Threshold * - * Motor failure triggers only above this throttle value. + * Failure detection per motor only triggers above this thrust value. + * Set to 1 to disable the detection. * * @group Failure Detector * @unit norm @@ -186,9 +187,11 @@ PARAM_DEFINE_INT32(FD_ACT_EN, 1); PARAM_DEFINE_FLOAT(FD_ACT_MOT_THR, 0.2f); /** - * Motor Failure Current/Throttle Threshold + * Motor Failure Current/Throttle Scale * - * Motor failure triggers only below this current value + * Determines the slope between expected steady state current and linearized, normalized thrust command. + * E.g. FD_ACT_MOT_C2T A represents the expected steady state current at 100%. + * FD_ACT_LOW_OFF and FD_ACT_HIGH_OFF offset the threshold from that slope. * * @group Failure Detector * @min 0.0 @@ -197,13 +200,12 @@ PARAM_DEFINE_FLOAT(FD_ACT_MOT_THR, 0.2f); * @decimal 2 * @increment 1 */ -PARAM_DEFINE_FLOAT(FD_ACT_MOT_C2T, 2.0f); +PARAM_DEFINE_FLOAT(FD_ACT_MOT_C2T, 35.f); /** - * Motor Failure Time Threshold + * Motor Failure Hysteresis Time * - * Motor failure triggers only if the throttle threshold and the - * current to throttle threshold are violated for this time. + * Motor failure only triggers after current thresholds are exceeded for this time. * * @group Failure Detector * @unit ms @@ -211,4 +213,32 @@ PARAM_DEFINE_FLOAT(FD_ACT_MOT_C2T, 2.0f); * @max 10000 * @increment 100 */ -PARAM_DEFINE_INT32(FD_ACT_MOT_TOUT, 100); +PARAM_DEFINE_INT32(FD_ACT_MOT_TOUT, 1000); + +/** + * Undercurrent motor failure limit offset + * + * threshold = FD_ACT_MOT_C2T * thrust - FD_ACT_LOW_OFF + * + * @group Failure Detector + * @min 0 + * @max 30 + * @unit A + * @decimal 2 + * @increment 1 + */ +PARAM_DEFINE_FLOAT(FD_ACT_LOW_OFF, 10.f); + +/** + * Overcurrent motor failure limit offset + * + * threshold = FD_ACT_MOT_C2T * thrust + FD_ACT_HIGH_OFF + * + * @group Failure Detector + * @min 0 + * @max 30 + * @unit A + * @decimal 2 + * @increment 1 + */ +PARAM_DEFINE_FLOAT(FD_ACT_HIGH_OFF, 10.f); From dbb00d500fbde89a6c635aa0dc616ba1c55fb8d9 Mon Sep 17 00:00:00 2001 From: Nick <145654544+ttechnick@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:35:47 +0100 Subject: [PATCH 52/71] Update src/modules/commander/failure_detector/FailureDetector.cpp Prevent Buffer overflow --- src/modules/commander/failure_detector/FailureDetector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/commander/failure_detector/FailureDetector.cpp b/src/modules/commander/failure_detector/FailureDetector.cpp index b2eed03290..cbba4c68e0 100644 --- a/src/modules/commander/failure_detector/FailureDetector.cpp +++ b/src/modules/commander/failure_detector/FailureDetector.cpp @@ -329,7 +329,7 @@ void FailureDetector::updateMotorStatus(const vehicle_status_s &vehicle_status, _failure_detector_status.flags.motor = (_motor_failure_mask != 0u); } else { // Disarmed - for (uint8_t i = 0; i < actuator_motors_s::NUM_CONTROLS; ++i) { + for (uint8_t i = 0; i < esc_status_s::CONNECTED_ESC_MAX; ++i) { _esc_undercurrent_hysteresis[i].set_state_and_update(false, now); _esc_overcurrent_hysteresis[i].set_state_and_update(false, now); } From 1dbee4100a9d346a76048b8c070649c286b0425d Mon Sep 17 00:00:00 2001 From: Eric Katzfey Date: Thu, 5 Feb 2026 15:12:31 -0700 Subject: [PATCH 53/71] uORB: Added a new uorb_shutdown function that is called during normal shutdown procedures. It will only call into a new UORB COMMUNICATOR ICHANNEL shutdown interface if it has been configured, otherwise it does nothing. This allows ICHANNEL implementations to pass on a shutdown indication to a remote processor. Implemented the shutdown interface in the muorb module for VOXL flight controllers. --- platforms/common/apps.cpp.in | 2 ++ platforms/common/shutdown.cpp | 3 +++ platforms/common/uORB/uORB.cpp | 13 +++++++++++++ platforms/common/uORB/uORB.h | 1 + platforms/common/uORB/uORBCommunicator.hpp | 16 ++++++++++++++++ platforms/posix/src/px4/common/main.cpp | 2 ++ src/modules/muorb/apps/muorb_main.cpp | 4 +++- .../muorb/apps/uORBAppsProtobufChannel.cpp | 14 ++++++++++++++ .../muorb/apps/uORBAppsProtobufChannel.hpp | 11 +++++++++++ 9 files changed, 65 insertions(+), 1 deletion(-) diff --git a/platforms/common/apps.cpp.in b/platforms/common/apps.cpp.in index 11d1c50d9f..36c3ce6bdb 100644 --- a/platforms/common/apps.cpp.in +++ b/platforms/common/apps.cpp.in @@ -2,6 +2,7 @@ #include #include #include +#include #include "apps.h" @@ -43,6 +44,7 @@ void list_builtins(apps_map_type &apps) int shutdown_main(int argc, char *argv[]) { printf("Exiting NOW.\n"); + uorb_shutdown(); system_exit(0); } diff --git a/platforms/common/shutdown.cpp b/platforms/common/shutdown.cpp index 878d99c62e..d1be7ff5a1 100644 --- a/platforms/common/shutdown.cpp +++ b/platforms/common/shutdown.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -173,6 +174,8 @@ static void shutdown_worker(void *arg) const bool delay_elapsed = (now > shutdown_time_us); if (delay_elapsed && ((done && shutdown_lock_counter == 0) || (now > (shutdown_time_us + shutdown_timeout_us)))) { + uorb_shutdown(); + if (shutdown_args & SHUTDOWN_ARG_REBOOT) { #if defined(CONFIG_BOARDCTL_RESET) PX4_INFO_RAW("Reboot NOW."); diff --git a/platforms/common/uORB/uORB.cpp b/platforms/common/uORB/uORB.cpp index a68f3c5dc8..dd08a8e067 100644 --- a/platforms/common/uORB/uORB.cpp +++ b/platforms/common/uORB/uORB.cpp @@ -51,6 +51,7 @@ #include #endif + static uORB::DeviceMaster *g_dev = nullptr; int uorb_start(void) @@ -113,6 +114,18 @@ int uorb_top(char **topic_filter, int num_filters) return OK; } +void uorb_shutdown(void) +{ +#ifdef CONFIG_ORB_COMMUNICATOR + uORBCommunicator::IChannel *ch = uORB::Manager::get_instance()->get_uorb_communicator(); + + if (ch) { + ch->shutdown(); + } + +#endif /* CONFIG_ORB_COMMUNICATOR */ +} + orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data) { return uORB::Manager::get_instance()->orb_advertise(meta, data); diff --git a/platforms/common/uORB/uORB.h b/platforms/common/uORB/uORB.h index ee11923b59..bfdf46fab8 100644 --- a/platforms/common/uORB/uORB.h +++ b/platforms/common/uORB/uORB.h @@ -121,6 +121,7 @@ __BEGIN_DECLS int uorb_start(void); int uorb_status(void); int uorb_top(char **topic_filter, int num_filters); +void uorb_shutdown(void); /** * ORB topic advertiser handle. diff --git a/platforms/common/uORB/uORBCommunicator.hpp b/platforms/common/uORB/uORBCommunicator.hpp index 8122b34780..64706f29bf 100644 --- a/platforms/common/uORB/uORBCommunicator.hpp +++ b/platforms/common/uORB/uORBCommunicator.hpp @@ -129,6 +129,22 @@ public: virtual int16_t send_message(const char *messageName, int32_t length, uint8_t *data) = 0; + + //========================================================================= + // INTERFACES FOR Lifecycle messages + //========================================================================= + + /** + * @brief Interface to notify the remote entity of a shutdown. + * + * @return + * 0 = success; This means the shutdown is successfully sent to the receiver + * Note: This does not mean that the receiver has received it. + * otherwise = failure. + */ + + virtual int16_t shutdown() { return 0; } + }; /** diff --git a/platforms/posix/src/px4/common/main.cpp b/platforms/posix/src/px4/common/main.cpp index db6bfe850b..87af3b7344 100644 --- a/platforms/posix/src/px4/common/main.cpp +++ b/platforms/posix/src/px4/common/main.cpp @@ -73,6 +73,7 @@ #include #include #include +#include #include "apps.h" #include "px4_daemon/client.h" @@ -505,6 +506,7 @@ void sig_int_handler(int sig_num) fflush(stdout); printf("\nPX4 Exiting...\n"); fflush(stdout); + uorb_shutdown(); px4_daemon::Pxh::stop(); _exit_requested = true; } diff --git a/src/modules/muorb/apps/muorb_main.cpp b/src/modules/muorb/apps/muorb_main.cpp index d3c4d78cec..8db18141e0 100644 --- a/src/modules/muorb/apps/muorb_main.cpp +++ b/src/modules/muorb/apps/muorb_main.cpp @@ -58,7 +58,9 @@ muorb_init() if (channel && channel->Initialize(enable_debug)) { uORB::Manager::get_instance()->set_uorb_communicator(channel); - if (channel->Test()) { return OK; } + if (channel->Test()) { + return OK; + } } return -EINVAL; diff --git a/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp b/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp index 437e328156..df2376da27 100644 --- a/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp +++ b/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp @@ -291,6 +291,20 @@ int16_t uORB::AppsProtobufChannel::register_handler(uORBCommunicator::IChannelRx return 0; } +int16_t uORB::AppsProtobufChannel::shutdown() +{ + if (_ShutdownRequested) { + return 0; + } + + _ShutdownRequested = true; + + PX4_ERR("Sending kill command to SLPI!!!"); + fc_sensor_kill_slpi(); + sleep(1); + return 0; +} + int16_t uORB::AppsProtobufChannel::send_message(const char *messageName, int length, uint8_t *data) { // This is done to slow down high rate debug messages. diff --git a/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp b/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp index 7d280a460b..006a8714ef 100644 --- a/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp +++ b/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp @@ -147,6 +147,16 @@ public: */ int16_t send_message(const char *messageName, int length, uint8_t *data); + /** + * @brief Interface to notify the remote entity of a shutdown. + * + * @return + * 0 = success; This means the shutdown is successfully sent to the receiver + * Note: This does not mean that the receiver has received it. + * otherwise = failure. + */ + int16_t shutdown(); + /** * @brief Interface to test the functions of the protobuf channel. * @@ -169,6 +179,7 @@ private: static bool _Debug; bool _Initialized; + bool _ShutdownRequested{false}; uint32_t _MessageCounter; private: From aacb7e35ddf43a74bd2a6b5429b8de5e4d3862e9 Mon Sep 17 00:00:00 2001 From: Eric Katzfey Date: Sat, 7 Feb 2026 14:56:06 -0700 Subject: [PATCH 54/71] For VOXL flight controllers, Use DSP clock directly on Posix for CLOCK_MONOTONIC --- boards/modalai/voxl2/libfc-sensor-api | 2 +- platforms/posix/src/px4/common/drv_hrt.cpp | 40 ++++++++-------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/boards/modalai/voxl2/libfc-sensor-api b/boards/modalai/voxl2/libfc-sensor-api index 85151aaf6b..d5abf9cbbf 160000 --- a/boards/modalai/voxl2/libfc-sensor-api +++ b/boards/modalai/voxl2/libfc-sensor-api @@ -1 +1 @@ -Subproject commit 85151aaf6ba8b24ce82b387e088452c63f7e2096 +Subproject commit d5abf9cbbf07711db2a9166c2eec4a4a7682f921 diff --git a/platforms/posix/src/px4/common/drv_hrt.cpp b/platforms/posix/src/px4/common/drv_hrt.cpp index b510229bc0..1163f3fd8e 100644 --- a/platforms/posix/src/px4/common/drv_hrt.cpp +++ b/platforms/posix/src/px4/common/drv_hrt.cpp @@ -51,7 +51,7 @@ #include #include "hrt_work.h" -// Voxl2 board specific API definitions to get time offset +// Voxl board specific API definitions to get time #if defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) #include "fc_sensor.h" #endif @@ -112,29 +112,6 @@ hrt_abstime hrt_absolute_time() #else // defined(ENABLE_LOCKSTEP_SCHEDULER) struct timespec ts; px4_clock_gettime(CLOCK_MONOTONIC, &ts); - -# if defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) - hrt_abstime temp_abstime = ts_to_abstime(&ts); - int apps_time_offset = fc_sensor_get_time_offset(); - - if (apps_time_offset < 0) { - hrt_abstime temp_offset = -apps_time_offset; - - if (temp_offset >= temp_abstime) { - temp_abstime = 0; - - } else { - temp_abstime -= temp_offset; - } - - } else { - temp_abstime += (hrt_abstime) apps_time_offset; - } - - ts.tv_sec = temp_abstime / 1000000; - ts.tv_nsec = (temp_abstime % 1000000) * 1000; -# endif // defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) - return ts_to_abstime(&ts); #endif // defined(ENABLE_LOCKSTEP_SCHEDULER) } @@ -476,8 +453,21 @@ int px4_clock_gettime(clockid_t clk_id, struct timespec *tp) } #endif // defined(ENABLE_LOCKSTEP_SCHEDULER) - return system_clock_gettime(clk_id, tp); + int rv = system_clock_gettime(clk_id, tp); + +# if defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) + + // On VOXL use DSP clock as reference for MONOTONIC + if (clk_id == CLOCK_MONOTONIC) { + hrt_abstime temp_abstime = fc_sensor_get_dsp_timestamp_us(); + tp->tv_sec = temp_abstime / 1000000; + tp->tv_nsec = (temp_abstime % 1000000) * 1000; + } + +# endif // defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) + + return rv; } #if defined(ENABLE_LOCKSTEP_SCHEDULER) From 1b7e12cf90cdfbf084f18fda693825000401ab1f Mon Sep 17 00:00:00 2001 From: Eric Katzfey Date: Mon, 9 Feb 2026 15:06:49 -0700 Subject: [PATCH 55/71] VOXL_ESC: bringing the driver up to date with ModalAI latest. Includes new open loop "PWM" command handling. --- src/drivers/actuators/voxl_esc/module.yaml | 4 + src/drivers/actuators/voxl_esc/voxl_esc.cpp | 126 +++++++++++++----- src/drivers/actuators/voxl_esc/voxl_esc.hpp | 14 +- .../actuators/voxl_esc/voxl_esc_params.c | 28 ++++ 4 files changed, 138 insertions(+), 34 deletions(-) diff --git a/src/drivers/actuators/voxl_esc/module.yaml b/src/drivers/actuators/voxl_esc/module.yaml index c3bb1f4e6e..1a7e3fa319 100644 --- a/src/drivers/actuators/voxl_esc/module.yaml +++ b/src/drivers/actuators/voxl_esc/module.yaml @@ -19,6 +19,10 @@ actuator_output: label: 'ESC 3 Spin Direction' - param: 'VOXL_ESC_SDIR4' label: 'ESC 4 Spin Direction' + - param: 'VOXL_ESC_CMD' + label: 'ESC Command Type' + - param: 'VOXL_ESC_PWR_MIN' + label: 'ESC Minimum Power With PWM Command Type' output_groups: - param_prefix: VOXL_ESC group_label: 'ESCs' diff --git a/src/drivers/actuators/voxl_esc/voxl_esc.cpp b/src/drivers/actuators/voxl_esc/voxl_esc.cpp index 099a552a26..3414851b4b 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc.cpp +++ b/src/drivers/actuators/voxl_esc/voxl_esc.cpp @@ -300,6 +300,7 @@ int VoxlEsc::load_params(voxl_esc_params_t *params, ch_assign_t *map) param_get(param_find("VOXL_ESC_SDIR3"), ¶ms->direction_map[2]); param_get(param_find("VOXL_ESC_SDIR4"), ¶ms->direction_map[3]); + param_get(param_find("VOXL_ESC_PWR_MIN"), ¶ms->pwr_min); param_get(param_find("VOXL_ESC_RPM_MIN"), ¶ms->rpm_min); param_get(param_find("VOXL_ESC_RPM_MAX"), ¶ms->rpm_max); @@ -311,10 +312,23 @@ int VoxlEsc::load_params(voxl_esc_params_t *params, ch_assign_t *map) param_get(param_find("VOXL_ESC_GPIO_CH"), ¶ms->gpio_ctl_channel); - if (params->rpm_min >= params->rpm_max) { - PX4_ERR("Invalid parameter VOXL_ESC_RPM_MIN. Please verify parameters."); - params->rpm_min = 0; - ret = PX4_ERROR; + param_get(param_find("VOXL_ESC_CMD"), ¶ms->cmd_type); + + if (params->cmd_type > VOXL_ESC_PWM_CMDS) { + PX4_WARN("Warning, VOXL_ESC_CMD set to invalid value %d. Using 1 instead", (int) params->cmd_type); + params->cmd_type = VOXL_ESC_PWM_CMDS; + + } else if (params->cmd_type < VOXL_ESC_RPM_CMDS) { + PX4_WARN("Warning, VOXL_ESC_CMD set to invalid value %d. Using 0 instead", (int) params->cmd_type); + params->cmd_type = VOXL_ESC_RPM_CMDS; + } + + if (params->cmd_type == VOXL_ESC_RPM_CMDS) { + if (params->rpm_min >= params->rpm_max) { + PX4_ERR("Invalid parameter VOXL_ESC_RPM_MIN. Please verify parameters."); + params->rpm_min = 0; + ret = PX4_ERROR; + } } if (params->turtle_motor_percent < 0 || params->turtle_motor_percent > 100) { @@ -392,19 +406,24 @@ int VoxlEsc::task_spawn(int argc, char *argv[]) int ch; const char *myoptarg = nullptr; - while ((ch = px4_getopt(argc, argv, "dv", &myoptind, &myoptarg)) != EOF) { - switch (ch) { - case 'd': - _device = argv[myoptind]; - break; + VoxlEsc *instance = new VoxlEsc(); - default: - break; + // Parse any passed in options + if ((argc > 1) && (argv[1] != nullptr)) { + while ((ch = px4_getopt(argc - 1, &argv[1], "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + _device = argv[myoptind]; + PX4_INFO("Configuring device as %s", _device); + break; + + default: + PX4_ERR("Unknown option: %c", ch); + break; + } } } - VoxlEsc *instance = new VoxlEsc(); - if (instance) { _object.store(instance); _task_id = task_id_is_work_queue; @@ -571,6 +590,8 @@ int VoxlEsc::parse_response(uint8_t *buf, uint8_t len, bool print_feedback) QC_ESC_FB_POWER_STATUS packet; memcpy(&packet, _fb_packet.buffer, packet_size); + _rx_power_status_count++; + float voltage = packet.voltage * 0.001f; // Voltage is reported at 1 mV resolution float current = packet.current * 0.008f; // Total current is reported at 8mA resolution @@ -907,8 +928,19 @@ int VoxlEsc::update_params() if (ret == PX4_OK) { _mixing_output.setAllDisarmedValues(0); _mixing_output.setAllFailsafeValues(0); - _mixing_output.setAllMinValues(_parameters.rpm_min); - _mixing_output.setAllMaxValues(_parameters.rpm_max); + + if (_parameters.cmd_type == VOXL_ESC_RPM_CMDS) { + _mixing_output.setAllMinValues(_parameters.rpm_min); + _mixing_output.setAllMaxValues(_parameters.rpm_max); + + } else if (_parameters.cmd_type == VOXL_ESC_PWM_CMDS) { + // we use a minimum value of 1, since 0 is for disarmed + _min_active_pwm = math::constrain(static_cast((_parameters.pwr_min * + static_cast(VOXL_ESC_PWM_MAX))), + VOXL_ESC_PWM_MIN, VOXL_ESC_PWM_MAX); + _mixing_output.setAllMinValues(_min_active_pwm); + _mixing_output.setAllMaxValues(VOXL_ESC_PWM_MAX); + } _rpm_fullscale = _parameters.rpm_max - _parameters.rpm_min; } @@ -1216,11 +1248,18 @@ bool VoxlEsc::updateOutputs(uint16_t outputs[MAX_ACTUATORS], _esc_chans[i].rate_req = 0; } else { - if (_extended_rpm) { - if (outputs[i] > VOXL_ESC_RPM_MAX_EXT) { outputs[i] = VOXL_ESC_RPM_MAX_EXT; } + if ((_turtle_mode_en) || (_parameters.cmd_type == VOXL_ESC_RPM_CMDS)) { + if (_extended_rpm) { + if (outputs[i] > VOXL_ESC_RPM_MAX_EXT) { outputs[i] = VOXL_ESC_RPM_MAX_EXT; } - } else { - if (outputs[i] > VOXL_ESC_RPM_MAX) { outputs[i] = VOXL_ESC_RPM_MAX; } + } else { + if (outputs[i] > VOXL_ESC_RPM_MAX) { outputs[i] = VOXL_ESC_RPM_MAX; } + } + + } else if (_parameters.cmd_type == VOXL_ESC_PWM_CMDS) { + if (outputs[i] > VOXL_ESC_PWM_MAX) { outputs[i] = VOXL_ESC_PWM_MAX; } + + else if (outputs[i] < _min_active_pwm) { outputs[i] = _min_active_pwm; } } if (!_turtle_mode_en) { @@ -1235,18 +1274,34 @@ bool VoxlEsc::updateOutputs(uint16_t outputs[MAX_ACTUATORS], Command cmd; - cmd.len = qc_esc_create_rpm_packet4_fb(_esc_chans[0].rate_req, - _esc_chans[1].rate_req, - _esc_chans[2].rate_req, - _esc_chans[3].rate_req, - _esc_chans[0].led, - _esc_chans[1].led, - _esc_chans[2].led, - _esc_chans[3].led, - _fb_idx, - cmd.buf, - sizeof(cmd.buf), - _extended_rpm); + + if (_parameters.cmd_type == VOXL_ESC_RPM_CMDS) { + cmd.len = qc_esc_create_rpm_packet4_fb(_esc_chans[0].rate_req, + _esc_chans[1].rate_req, + _esc_chans[2].rate_req, + _esc_chans[3].rate_req, + _esc_chans[0].led, + _esc_chans[1].led, + _esc_chans[2].led, + _esc_chans[3].led, + _fb_idx, + cmd.buf, + sizeof(cmd.buf), + _extended_rpm); + + } else if (_parameters.cmd_type == VOXL_ESC_PWM_CMDS) { + cmd.len = qc_esc_create_pwm_packet4_fb(_esc_chans[0].rate_req, + _esc_chans[1].rate_req, + _esc_chans[2].rate_req, + _esc_chans[3].rate_req, + _esc_chans[0].led, + _esc_chans[1].led, + _esc_chans[2].led, + _esc_chans[3].led, + _fb_idx, + cmd.buf, + sizeof(cmd.buf)); + } if (_uart_port.write(cmd.buf, cmd.len) != cmd.len) { PX4_ERR("Failed to send packet"); @@ -1631,6 +1686,8 @@ void VoxlEsc::print_params() PX4_INFO("Params: VOXL_ESC_SDIR3: %" PRId32, _parameters.direction_map[2]); PX4_INFO("Params: VOXL_ESC_SDIR4: %" PRId32, _parameters.direction_map[3]); + PX4_INFO("Params: VOXL_ESC_PWR_MIN: %f", (double) _parameters.pwr_min); + PX4_INFO("Params: VOXL_ESC_RPM_MIN: %" PRId32, _parameters.rpm_min); PX4_INFO("Params: VOXL_ESC_RPM_MAX: %" PRId32, _parameters.rpm_max); @@ -1647,6 +1704,8 @@ void VoxlEsc::print_params() PX4_INFO("Params: VOXL_ESC_T_OVER: %" PRId32, _parameters.esc_over_temp_threshold); PX4_INFO("Params: VOXL_ESC_GPIO_CH: %" PRId32, _parameters.gpio_ctl_channel); + + PX4_INFO("Params: VOXL_ESC_CMD: %" PRId32, _parameters.cmd_type); } int VoxlEsc::print_status() @@ -1656,6 +1715,10 @@ int VoxlEsc::print_status() PX4_INFO("UART port: %s", _device); PX4_INFO("UART open: %s", _uart_port.isOpen() ? "yes" : "no"); + PX4_INFO("CRC error count: %lu", (long unsigned int) _rx_crc_error_count); + PX4_INFO("Packet RX count: %lu", (long unsigned int) _rx_packet_count); + PX4_INFO("Power status count: %lu", (long unsigned int) _rx_power_status_count); + PX4_INFO(""); print_params(); PX4_INFO(""); @@ -1695,6 +1758,7 @@ const char * VoxlEsc::board_id_to_name(int board_id) case 40: return "ModalAi 4-in-1 ESC (M0129-3)"; case 41: return "ModalAi 4-in-1 ESC (M0134-6)"; case 42: return "ModalAi 4-in-1 ESC (M0138-1)"; + case 44: return "ModalAi 4-in-1 ESC (M0129-6)"; default: return "Unknown Board"; } } diff --git a/src/drivers/actuators/voxl_esc/voxl_esc.hpp b/src/drivers/actuators/voxl_esc/voxl_esc.hpp index ee8b931f07..d103f902d0 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc.hpp +++ b/src/drivers/actuators/voxl_esc/voxl_esc.hpp @@ -117,8 +117,8 @@ private: static constexpr uint16_t DISARMED_VALUE = 0; - static constexpr uint16_t VOXL_ESC_PWM_MIN = 0; - static constexpr uint16_t VOXL_ESC_PWM_MAX = 800; + static constexpr int VOXL_ESC_PWM_MIN = 1; + static constexpr int VOXL_ESC_PWM_MAX = 800; static constexpr uint16_t VOXL_ESC_DEFAULT_RPM_MIN = 5000; static constexpr uint16_t VOXL_ESC_DEFAULT_RPM_MAX = 17000; @@ -148,6 +148,9 @@ private: static constexpr uint32_t VOXL_ESC_GPIO_CTL_AUX5 = 5; static constexpr uint32_t VOXL_ESC_GPIO_CTL_AUX6 = 6; + static constexpr int32_t VOXL_ESC_RPM_CMDS = 0; + static constexpr int32_t VOXL_ESC_PWM_CMDS = 1; + Serial _uart_port{}; typedef struct { @@ -159,6 +162,7 @@ private: float turtle_stick_minf{0.15f}; float turtle_cosphi{0.99f}; int32_t baud_rate{VOXL_ESC_DEFAULT_BAUD}; + float pwr_min{0.05f}; int32_t rpm_min{VOXL_ESC_DEFAULT_RPM_MIN}; int32_t rpm_max{VOXL_ESC_DEFAULT_RPM_MAX}; int32_t function_map[VOXL_ESC_OUTPUT_CHANNELS] {0, 0, 0, 0}; @@ -169,6 +173,7 @@ private: int32_t esc_warn_temp_threshold{0}; int32_t esc_over_temp_threshold{0}; int32_t gpio_ctl_channel{0}; + int32_t cmd_type{0}; } voxl_esc_params_t; struct EscChan { @@ -222,6 +227,8 @@ private: bool _need_version_info{true}; QC_ESC_EXTENDED_VERSION_INFO _version_info[VOXL_ESC_OUTPUT_CHANNELS]; + int _min_active_pwm{1}; + voxl_esc_params_t _parameters; int update_params(); int load_params(voxl_esc_params_t *params, ch_assign_t *map); @@ -250,12 +257,13 @@ private: int _fb_idx; uint32_t _rx_crc_error_count{0}; uint32_t _rx_packet_count{0}; + uint32_t _rx_power_status_count{0}; static const uint8_t READ_BUF_SIZE = 128; uint8_t _read_buf[READ_BUF_SIZE]; Battery _battery; - static constexpr unsigned _battery_report_interval{100_ms}; + static constexpr unsigned _battery_report_interval{20_ms}; hrt_abstime _last_battery_report_time; hrt_abstime _last_uart_passthru{0}; diff --git a/src/drivers/actuators/voxl_esc/voxl_esc_params.c b/src/drivers/actuators/voxl_esc/voxl_esc_params.c index b0526ecf1f..6ccfeb60ba 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc_params.c +++ b/src/drivers/actuators/voxl_esc/voxl_esc_params.c @@ -276,3 +276,31 @@ PARAM_DEFINE_INT32(VOXL_ESC_T_OVER, 0); * @max 6 */ PARAM_DEFINE_INT32(VOXL_ESC_GPIO_CH, 0); + +/** + * UART ESC command type + * + * Selects between RPM or PWM commands + * + * @reboot_required true + * + * @group VOXL ESC + * @value 0 - RPM + * @value 1 - PWM + * @min 0 + * @max 1 + */ +PARAM_DEFINE_INT32(VOXL_ESC_CMD, 0); + +/** + * UART ESC Minimum motor power + * + * Minimum motor power for ESC when VOXL_ESC_CMD is set for PWM. + * Make sure to set this high enough so that the motors are always spinning + * while armed. + * + * @group VOXL ESC + * @min 0.0 + * @max 1.0 + */ +PARAM_DEFINE_FLOAT(VOXL_ESC_PWR_MIN, 0.05); From 833e4536b70787d746e4e20e0c8749c8a5d45dac Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Thu, 8 Jan 2026 16:47:23 +1300 Subject: [PATCH 56/71] nuttx: add support for NAND flash This cherry-picks upstream commits adding NAND flash support for the Winbond W25N specifically W25N01GV chip. NAND flash is used together with littlefs, hence I updated that to 2.5.1 to match upstream NuttX. --- platforms/nuttx/NuttX/nuttx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/nuttx/NuttX/nuttx b/platforms/nuttx/NuttX/nuttx index 201d8b01f1..f34ff89edf 160000 --- a/platforms/nuttx/NuttX/nuttx +++ b/platforms/nuttx/NuttX/nuttx @@ -1 +1 @@ -Subproject commit 201d8b01f14269a9647ef6da499214ffd39ff8f0 +Subproject commit f34ff89edf9764fdd177f3faa616d85ebf2778f2 From d411e1c40d120c60b474567fad5dcdf477c4fbd3 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Thu, 8 Jan 2026 17:24:11 +1300 Subject: [PATCH 57/71] logger: increase stack size for littlefs --- src/modules/logger/log_writer_file.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/logger/log_writer_file.cpp b/src/modules/logger/log_writer_file.cpp index 851bcec719..1ec37cf73e 100644 --- a/src/modules/logger/log_writer_file.cpp +++ b/src/modules/logger/log_writer_file.cpp @@ -291,7 +291,11 @@ int LogWriterFile::thread_start() param.sched_priority = SCHED_PRIORITY_DEFAULT - 40; (void)pthread_attr_setschedparam(&thr_attr, ¶m); +#ifdef CONFIG_FS_LITTLEFS + pthread_attr_setstacksize(&thr_attr, PX4_STACK_ADJUSTED(1800)); /* littlefs needs more stack */ +#else pthread_attr_setstacksize(&thr_attr, PX4_STACK_ADJUSTED(1170)); +#endif int ret = pthread_create(&_thread, &thr_attr, &LogWriterFile::run_helper, this); pthread_attr_destroy(&thr_attr); From 0294d4a794110c5385661f0df4e6ba2e2da1b52d Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Mon, 29 Dec 2025 17:14:43 +1300 Subject: [PATCH 58/71] dataman: increase stack size for littlefs Increase stack size when using littlefs filesystem, which requires more stack space than traditional filesystems. --- src/modules/dataman/dataman.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/dataman/dataman.cpp b/src/modules/dataman/dataman.cpp index 8cefa477bc..ae5d294fda 100644 --- a/src/modules/dataman/dataman.cpp +++ b/src/modules/dataman/dataman.cpp @@ -63,7 +63,11 @@ __BEGIN_DECLS __EXPORT int dataman_main(int argc, char *argv[]); __END_DECLS +#ifdef CONFIG_FS_LITTLEFS +static constexpr int TASK_STACK_SIZE = 2000; /* littlefs needs more stack */ +#else static constexpr int TASK_STACK_SIZE = 1420; +#endif #ifdef CONFIG_DATAMAN_PERSISTENT_STORAGE /* Private File based Operations */ From e0af9f4ef4f5ccff2ddf8d33ab28bd7b589d0edf Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Fri, 19 Dec 2025 09:55:11 +1300 Subject: [PATCH 59/71] boards: add NAND flash logging support to KakuteH7v2 - Initialize W25N01GV NAND flash on SPI1 with littlefs. - Enable BOARD_SMALL_FLASH_LOGGING for small flash handling. - Increase logger buffer size for flash write performance. --- .../holybro/kakuteh7v2/init/rc.board_defaults | 5 +- .../kakuteh7v2/nuttx-config/include/board.h | 18 +++---- .../nuttx-config/include/board_dma_map.h | 4 ++ .../kakuteh7v2/nuttx-config/nsh/defconfig | 16 ++++-- boards/holybro/kakuteh7v2/src/board_config.h | 5 ++ boards/holybro/kakuteh7v2/src/init.c | 51 +++++++++++++++++-- boards/holybro/kakuteh7v2/src/spi.cpp | 2 +- 7 files changed, 79 insertions(+), 22 deletions(-) diff --git a/boards/holybro/kakuteh7v2/init/rc.board_defaults b/boards/holybro/kakuteh7v2/init/rc.board_defaults index f2534d1709..de1eecef02 100644 --- a/boards/holybro/kakuteh7v2/init/rc.board_defaults +++ b/boards/holybro/kakuteh7v2/init/rc.board_defaults @@ -38,5 +38,6 @@ param set-default SYS_DM_BACKEND 1 # Ignore that there is no SD card param set-default COM_ARM_SDCARD 0 -# Disable logging -param set-default SDLOG_BACKEND 0 +# W25N NAND flash with littlefs (128 MB): larger buffer, auto-rotate +set LOGGER_BUF 32 +param set-default SDLOG_DIRS_MAX 3 diff --git a/boards/holybro/kakuteh7v2/nuttx-config/include/board.h b/boards/holybro/kakuteh7v2/nuttx-config/include/board.h index 0c96869f01..9d23954dab 100644 --- a/boards/holybro/kakuteh7v2/nuttx-config/include/board.h +++ b/boards/holybro/kakuteh7v2/nuttx-config/include/board.h @@ -99,7 +99,7 @@ * PLL1_VCO = (8,000,000 / 1) * 120 = 960 MHz * * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz - * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1Q = PLL1_VCO/5 = 960 MHz / 5 = 192 MHz (SPI123 clock, max 200 MHz) * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz */ @@ -111,12 +111,12 @@ #define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) #define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(120) #define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) -#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(5) #define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) #define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 120) #define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) -#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 5) #define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) /* PLL2 */ @@ -227,9 +227,9 @@ #define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI -/* SPI123 clock source */ +/* SPI123 clock source - PLL1Q = 192 MHz for W25N NAND flash (max 104 MHz) */ -#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL1 /* SPI45 clock source */ @@ -281,17 +281,17 @@ #define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) -/* 25 MHz Max for now, 25 mHZ = PLL1Q/(2*div), div = PLL1Q/(2*freq) - * div = 4.8 = 240 / 50, So round up to 5 for default speed 24 MB/s +/* 25 MHz Max for now, 25 mHz = PLL1Q/(2*div), div = PLL1Q/(2*freq) + * PLL1Q = 192 MHz, div = 192 / 50 = 3.84, round up to 4 for 24 MHz */ #if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) -# define STM32_SDMMC_MMCXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_MMCXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else # define STM32_SDMMC_MMCXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif #if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) -# define STM32_SDMMC_SDXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_SDXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else # define STM32_SDMMC_SDXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif diff --git a/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h b/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h index d23e0d4120..1a84c705b7 100644 --- a/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h +++ b/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h @@ -33,6 +33,10 @@ #pragma once +/* SPI1 DMA for W25N NAND Flash */ +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* DMA1 */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* DMA1 */ + #define DMAMAP_SPI4_RX DMAMAP_DMA12_SPI4RX_1 /* DMA2 */ #define DMAMAP_SPI4_TX DMAMAP_DMA12_SPI4TX_1 /* DMA2 */ diff --git a/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig b/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig index 7e8e989a85..d76ab2b90c 100644 --- a/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig +++ b/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig @@ -104,6 +104,10 @@ CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y CONFIG_FS_PROCFS_MAX_TASKS=64 CONFIG_FS_PROCFS_REGISTER=y CONFIG_FS_ROMFS=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_READ_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=1 CONFIG_GRAN=y CONFIG_GRAN_INTR=y CONFIG_HAVE_CXX=y @@ -126,7 +130,9 @@ CONFIG_MTD=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_PROGMEM=y -CONFIG_MTD_RAMTRON=y +# CONFIG_MTD_RAMTRON is not set +CONFIG_MTD_W25N=y +CONFIG_W25N_SPIFREQUENCY=104000000 CONFIG_NAME_MAX=40 CONFIG_NSH_ARCHINIT=y CONFIG_NSH_ARGCAT=y @@ -135,7 +141,7 @@ CONFIG_NSH_CMDPARMS=y CONFIG_NSH_CROMFSETC=y CONFIG_NSH_LINELEN=128 CONFIG_NSH_MAXARGUMENTS=15 -CONFIG_NSH_MMCSDSPIPORTNO=1 +# CONFIG_NSH_MMCSDSPIPORTNO is not set CONFIG_NSH_NESTDEPTH=8 CONFIG_NSH_QUOTE=y CONFIG_NSH_ROMFSETC=y @@ -148,9 +154,6 @@ CONFIG_PREALLOC_TIMERS=50 CONFIG_PRIORITY_INHERITANCE=y CONFIG_PTHREAD_MUTEX_ROBUST=y CONFIG_PTHREAD_STACK_MIN=512 -CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5 -CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5 -CONFIG_RAMTRON_SETSPEED=y CONFIG_RAM_SIZE=245760 CONFIG_RAM_START=0x20010000 CONFIG_RAW_BINARY=y @@ -188,6 +191,7 @@ CONFIG_STM32H7_BKPSRAM=y CONFIG_STM32H7_DMA1=y CONFIG_STM32H7_DMA2=y CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_DMAMUX1=y CONFIG_STM32H7_FLOWCONTROL_BROKEN=y CONFIG_STM32H7_I2C1=y CONFIG_STM32H7_I2C_DYNTIMEO=y @@ -202,6 +206,8 @@ CONFIG_STM32H7_SDMMC1=y CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=4096 CONFIG_STM32H7_SPI2=y CONFIG_STM32H7_SPI4=y CONFIG_STM32H7_SPI4_DMA=y diff --git a/boards/holybro/kakuteh7v2/src/board_config.h b/boards/holybro/kakuteh7v2/src/board_config.h index c8ec2fabe1..292dc706ce 100644 --- a/boards/holybro/kakuteh7v2/src/board_config.h +++ b/boards/holybro/kakuteh7v2/src/board_config.h @@ -59,6 +59,11 @@ # define BOARD_HAS_NBAT_V 1 # define BOARD_HAS_NBAT_I 1 +/* Enable small flash logging support (for W25N NAND flash) */ +#ifdef CONFIG_MTD_W25N +# define BOARD_SMALL_FLASH_LOGGING 1 +#endif + /* Holybro KakuteH7 GPIOs ************************************************************************/ /* LEDs are driven with push open drain to support Anode to 5V or 3.3V */ diff --git a/boards/holybro/kakuteh7v2/src/init.c b/boards/holybro/kakuteh7v2/src/init.c index bff6e6535a..2ca4532fdd 100644 --- a/boards/holybro/kakuteh7v2/src/init.c +++ b/boards/holybro/kakuteh7v2/src/init.c @@ -59,6 +59,8 @@ #include #include #include +#include +#include #include #include #include @@ -79,6 +81,10 @@ # include #endif +#ifdef CONFIG_MTD_W25N +extern FAR struct mtd_dev_s *w25n_initialize(FAR struct spi_dev_s *dev, uint32_t spi_devid); +#endif + /**************************************************************************** * Pre-Processor Definitions @@ -231,14 +237,49 @@ __EXPORT int board_app_initialize(uintptr_t arg) led_on(LED_RED); } - /* Get the SPI port for the microSD slot */ - struct spi_dev_s *spi_dev = stm32_spibus_initialize(CONFIG_NSH_MMCSDSPIPORTNO); +#ifdef CONFIG_MTD_W25N + /* Initialize W25N01GV NAND Flash on SPI1 */ + struct spi_dev_s *spi1 = stm32_spibus_initialize(1); - if (!spi_dev) { - syslog(LOG_ERR, "[boot] FAILED to initialize SPI port %d\n", CONFIG_NSH_MMCSDSPIPORTNO); - led_on(LED_BLUE); + if (!spi1) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI1 for W25N\n"); + led_on(LED_RED); + + } else { + struct mtd_dev_s *mtd = w25n_initialize(spi1, 0); + + if (!mtd) { + syslog(LOG_ERR, "[boot] FAILED to initialize W25N MTD driver\n"); + led_on(LED_RED); + + } else { + int ret = register_mtddriver("/dev/mtd0", mtd, 0755, NULL); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to register MTD driver: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); + +#ifdef CONFIG_FS_LITTLEFS + ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, "autoformat"); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to mount littlefs: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] LittleFS mounted at /fs/microsd\n"); + } + +#endif + } + } } +#endif + up_udelay(20); diff --git a/boards/holybro/kakuteh7v2/src/spi.cpp b/boards/holybro/kakuteh7v2/src/spi.cpp index a8ce482c5d..80f1896c5f 100644 --- a/boards/holybro/kakuteh7v2/src/spi.cpp +++ b/boards/holybro/kakuteh7v2/src/spi.cpp @@ -37,7 +37,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::SPI1, { - initSPIDevice(SPIDEV_MMCSD(0), SPI::CS{GPIO::PortA, GPIO::Pin4}) + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortA, GPIO::Pin4}) // W25N01GV NAND Flash }), initSPIBus(SPI::Bus::SPI2, { initSPIDevice(DRV_OSD_DEVTYPE_ATXXXX, SPI::CS{GPIO::PortB, GPIO::Pin12}), From 3a6a57bd45c3565796152e33bd0f569acd649d63 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Tue, 3 Feb 2026 10:40:33 +1300 Subject: [PATCH 60/71] kakuteh7v2: use /fs/flash instead of /fs/microsd --- boards/holybro/kakuteh7v2/default.px4board | 1 + boards/holybro/kakuteh7v2/src/init.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/boards/holybro/kakuteh7v2/default.px4board b/boards/holybro/kakuteh7v2/default.px4board index d5d93c948b..11a83271c8 100644 --- a/boards/holybro/kakuteh7v2/default.px4board +++ b/boards/holybro/kakuteh7v2/default.px4board @@ -1,5 +1,6 @@ CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROOT_PATH="/fs/flash" CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS3" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS0" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS1" diff --git a/boards/holybro/kakuteh7v2/src/init.c b/boards/holybro/kakuteh7v2/src/init.c index 2ca4532fdd..5cc65b069d 100644 --- a/boards/holybro/kakuteh7v2/src/init.c +++ b/boards/holybro/kakuteh7v2/src/init.c @@ -263,14 +263,14 @@ __EXPORT int board_app_initialize(uintptr_t arg) syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); #ifdef CONFIG_FS_LITTLEFS - ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, "autoformat"); + ret = nx_mount("/dev/mtd0", CONFIG_BOARD_ROOT_PATH, "littlefs", 0, "autoformat"); if (ret < 0) { syslog(LOG_ERR, "[boot] FAILED to mount littlefs: %d\n", ret); led_on(LED_RED); } else { - syslog(LOG_INFO, "[boot] LittleFS mounted at /fs/microsd\n"); + syslog(LOG_INFO, "[boot] LittleFS mounted at %s\n", CONFIG_BOARD_ROOT_PATH); } #endif From 14864814ef82ec961ca6bd24886f4674fa81f108 Mon Sep 17 00:00:00 2001 From: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> Date: Tue, 10 Feb 2026 11:43:39 +0900 Subject: [PATCH 61/71] gps: ubx: added jamming sensitivity parameter (#26386) * gps: ubx: added jamming sensitivity parameter GPS_UBX_JAM_DET * submodule * gps: submodule to main --- src/drivers/gps/devices | 2 +- src/drivers/gps/gps.cpp | 8 ++++++++ src/drivers/gps/params.c | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/drivers/gps/devices b/src/drivers/gps/devices index a213f386d3..5ed844c374 160000 --- a/src/drivers/gps/devices +++ b/src/drivers/gps/devices @@ -1 +1 @@ -Subproject commit a213f386d3fdae0cf497bb80b41bcc9c0c9e1614 +Subproject commit 5ed844c374646bfa2b41461c909a3b4df1a17233 diff --git a/src/drivers/gps/gps.cpp b/src/drivers/gps/gps.cpp index 5fc2598848..f6cc8f8e75 100644 --- a/src/drivers/gps/gps.cpp +++ b/src/drivers/gps/gps.cpp @@ -851,6 +851,13 @@ GPS::run() param_get(handle, &ppk_output); } + handle = param_find("GPS_UBX_JAM_DET"); + int32_t jam_det_sensitivity_hi = 1; + + if (handle != PARAM_INVALID) { + param_get(handle, &jam_det_sensitivity_hi); + } + int32_t gnssSystemsParam = static_cast(GPSHelper::GNSSSystemsMask::RECEIVER_DEFAULTS); if (_instance == Instance::Main) { @@ -941,6 +948,7 @@ GPS::run() .heading_offset = heading_offset, .uart2_baudrate = f9p_uart2_baudrate, .ppk_output = ppk_output > 0, + .jam_det_sensitivity_hi = jam_det_sensitivity_hi > 0, .mode = ubx_mode, }; diff --git a/src/drivers/gps/params.c b/src/drivers/gps/params.c index 2dc7dcd298..dd37f58486 100644 --- a/src/drivers/gps/params.c +++ b/src/drivers/gps/params.c @@ -198,6 +198,20 @@ PARAM_DEFINE_INT32(GPS_UBX_CFG_INTF, 0); */ PARAM_DEFINE_INT32(GPS_UBX_PPK, 0); +/** + * u-blox GPS jamming detection high sensitivity mode + * + * Enables or disables the high sensitivity mode for the u-blox jamming detection + * (CFG-SEC-JAMDET_SENSITIVITY_HI). When enabled, the receiver uses a + * more sensitive algorithm to detect jamming. Disabling this may reduce false + * positives in electrically noisy environments. + * + * @boolean + * @reboot_required true + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_JAM_DET, 1); + /** * Wipes the flash config of UBX modules. * From ea2ca45cf96e359f85c09dbfc6b80dbe49e006ec Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Mon, 29 Dec 2025 17:15:20 +1300 Subject: [PATCH 62/71] boards: add support for Gear Up AirBrainH743 --- .../gearup/airbrainh743/bootloader.px4board | 3 + boards/gearup/airbrainh743/default.px4board | 85 +++++ .../extras/gearup_airbrainh743_bootloader.bin | Bin 0 -> 42648 bytes boards/gearup/airbrainh743/firmware.prototype | 13 + .../airbrainh743/init/rc.board_defaults | 17 + .../gearup/airbrainh743/init/rc.board_extras | 6 + .../gearup/airbrainh743/init/rc.board_sensors | 16 + .../gearup/airbrainh743/nuttx-config/Kconfig | 3 + .../nuttx-config/bootloader/defconfig | 89 +++++ .../airbrainh743/nuttx-config/include/board.h | 339 ++++++++++++++++++ .../nuttx-config/include/board_dma_map.h | 42 +++ .../airbrainh743/nuttx-config/nsh/defconfig | 257 +++++++++++++ .../nuttx-config/scripts/bootloader_script.ld | 213 +++++++++++ .../nuttx-config/scripts/script.ld | 228 ++++++++++++ boards/gearup/airbrainh743/src/CMakeLists.txt | 67 ++++ boards/gearup/airbrainh743/src/board_config.h | 216 +++++++++++ .../gearup/airbrainh743/src/bootloader_main.c | 75 ++++ boards/gearup/airbrainh743/src/hw_config.h | 85 +++++ boards/gearup/airbrainh743/src/i2c.cpp | 45 +++ boards/gearup/airbrainh743/src/init.c | 228 ++++++++++++ boards/gearup/airbrainh743/src/led.c | 205 +++++++++++ boards/gearup/airbrainh743/src/spi.cpp | 58 +++ .../gearup/airbrainh743/src/timer_config.cpp | 70 ++++ boards/gearup/airbrainh743/src/usb.c | 75 ++++ docs/en/SUMMARY.md | 1 + .../autopilot_manufacturer_supported.md | 1 + .../flight_controller/gearup_airbrainh743.md | 96 +++++ 27 files changed, 2533 insertions(+) create mode 100644 boards/gearup/airbrainh743/bootloader.px4board create mode 100644 boards/gearup/airbrainh743/default.px4board create mode 100755 boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin create mode 100644 boards/gearup/airbrainh743/firmware.prototype create mode 100644 boards/gearup/airbrainh743/init/rc.board_defaults create mode 100644 boards/gearup/airbrainh743/init/rc.board_extras create mode 100644 boards/gearup/airbrainh743/init/rc.board_sensors create mode 100644 boards/gearup/airbrainh743/nuttx-config/Kconfig create mode 100644 boards/gearup/airbrainh743/nuttx-config/bootloader/defconfig create mode 100644 boards/gearup/airbrainh743/nuttx-config/include/board.h create mode 100644 boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h create mode 100644 boards/gearup/airbrainh743/nuttx-config/nsh/defconfig create mode 100644 boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld create mode 100644 boards/gearup/airbrainh743/nuttx-config/scripts/script.ld create mode 100644 boards/gearup/airbrainh743/src/CMakeLists.txt create mode 100644 boards/gearup/airbrainh743/src/board_config.h create mode 100644 boards/gearup/airbrainh743/src/bootloader_main.c create mode 100644 boards/gearup/airbrainh743/src/hw_config.h create mode 100644 boards/gearup/airbrainh743/src/i2c.cpp create mode 100644 boards/gearup/airbrainh743/src/init.c create mode 100644 boards/gearup/airbrainh743/src/led.c create mode 100644 boards/gearup/airbrainh743/src/spi.cpp create mode 100644 boards/gearup/airbrainh743/src/timer_config.cpp create mode 100644 boards/gearup/airbrainh743/src/usb.c create mode 100644 docs/en/flight_controller/gearup_airbrainh743.md diff --git a/boards/gearup/airbrainh743/bootloader.px4board b/boards/gearup/airbrainh743/bootloader.px4board new file mode 100644 index 0000000000..19b6e662be --- /dev/null +++ b/boards/gearup/airbrainh743/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/gearup/airbrainh743/default.px4board b/boards/gearup/airbrainh743/default.px4board new file mode 100644 index 0000000000..bcb4b2b786 --- /dev/null +++ b/boards/gearup/airbrainh743/default.px4board @@ -0,0 +1,85 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS6" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS3" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS5" +CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS2" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS1" +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_DPS310=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_COMMON_LIGHT=y +CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y +CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y +CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y +CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y +CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y +CONFIG_DRIVERS_OSD_MSP_OSD=y +CONFIG_COMMON_OPTICAL_FLOW=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +# CONFIG_EKF2_AUX_GLOBAL_POSITION is not set +# CONFIG_EKF2_AUXVEL is not set +# CONFIG_EKF2_BARO_COMPENSATION is not set +# CONFIG_EKF2_DRAG_FUSION is not set +# CONFIG_EKF2_GNSS_YAW is not set +# CONFIG_EKF2_SIDESLIP is not set +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_GYRO_FFT=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_USB_CONNECTED=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin b/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin new file mode 100755 index 0000000000000000000000000000000000000000..1363314125b33e07a4f8def73b8eef976d21724b GIT binary patch literal 42648 zcmeFZdw5jU^*6rHWoAw?flMywkOY`Z0!apRAfQ3K3^U>6GGMr98==*KpgkcLqM$~l zFd?WBv{Iril4=pWpjcr7u>_1kpw?@@GeB%0P@=IONKns^z?@v?{p=ZHTT6ex_x;Jwxrs`R7naBnu_WSOH>amI;KCXGvw}uUy_DniIP+TUSRWtoWsp#8tZlE~& zcFzUF28W$~AJ^>d7HYiRF*ViQ2{je@geU1j!&vv&f>UW9j7?0jC>;Buv!r@1^z?gnqO~bSHB~HbG`?P=F z_js2?@9~XN0eJeJ!khl(-jsfO(GfK>@^4R{gM4l}dx=arqB_#uxSI%glI~P?&Od^b z<~K3@Ei_F)dJ9@a(l-~T0zTO_}U?{CQgB%k>kBY*P znNEcTbWeH!bvS{|4*&H)m6lwn9`m0Z@C-5WTr-hqBQ z<~w@`+I9!pRzmL|#QlRukUy@@rFd~Vd%So*clh3d`zg_Tz$ov&!YI<&wXZ9&zQ7U&8CD#-<&R(^n#n0fbT@9}y%%fq2p zfB4qkaHahj(XXGl@--(}I~k^dj1z5=zA;VA^4LY9TvoFr znm*B=+(@hwC7Z`2R$wgo2;P#bT?)@tcPH0GIn`8fCpr_SqK+EWQGuCMGl`ZRpJ`~A zbY@%7z>k|KoaTZa7k6o~OYdQSGt@*HAtc2~K$^4h3UBDHG%YZBWTcquzo%YFGNMQ^OizH5o=N6`M z!CdR&oH{a7<@GN*`vVkabRp*3m}12{89ZnVxF9amm<3F7QM8{+T~3uxtpzkmH@FiD z^(Kp$<{`@7K8rZAkTVhGoj#OfIi{xFVpZ0D=+6U0A{d@-=Cv zxDUn<;R9Sr4PGnrR+-3);n1A0sWE=yne${aduFtU-D7A-1Mu! z#kx{Fy>dmq&=4KTiIa}2nYYmOko?Eo{G*vEAj*{9%0Cd{ljTgd&>;BP>{x$F;|Ytf zf+%BDViKBSS8#4xX6%XtPtgh$e2li+c(&&3=i1L7UVS|7_{nuA6DJZ)Y<%+QvDQq| zyt^CRp@G>)6kcWCBTdnJKHJkq6mI0=?&^_`xsRV4snF-cSAxpSAh@;%8TP;BC!JTu zWoGNzeCO10+i-0UX0n;tp;Kqo-+x)$xmo}Bb9!Z-%Fl4%8sF|aXC&KjnUTvyE|;Vs zSBYFDxfVGUIh7>R9D^J)g625nIDzJL$muwmi$^ZL>6|i-#fn0*!LXZ#Tgcq>-|wRR z{y*toX7;o;+DFtm&ZM$4iaV2BOS{LpiaV3@?(H6zSKK*j)_vXMW)*i{BmSa$oLJm> zZNAh!F2A_bSWwnIuAsPcbm6k@afQX5DMjVok8{)Z7k8%3Mwy>RarXHs z+8;jqcWo43!*$Vgdyr=j$iw~n{~8TGJAAovH~pTD8`^3eE+;yUJo~MTr7e~Sc3eUO zqwMWxFh@WWCZT~SM5X^#{UkfjZ%~+cPQ1y_+{CF&Dw93^q|z|6lgW5l_s9B)e)cA- z$}ZxvN1yzePSd3kuW3#mmn^zezI>l(5&14|q%J$D^($e8qSNX6S?A3TF58;7zL~#? z!Z6wF$!H0zZ*+yy^iCJ66K?v;dGcY0%w@NtR&g}fr@;jim;!UkeUUN zQTPMA^4WV#0izTjAkFqTmQX%;^K8a?^PFcae6T`mtEg@uW)o)ai($@cwA@%|eZ(%_ z=)SS|=y^?!*4k0cDNhYfD>R9>dN}3T{v0>+rX=Rvp5|e#whBh!`Y_iSPWeqQZ_V-K zNQ`aP8N1{qobq~aw%dp&yvJ1V%35&4{vFcTf;Q2oJ@q{>xl4i z8s%#wJsesX*0>#)A9F4>ljnJ~w@o#Pl&_KIr?(Jc6Zj8>)40LgmkeEj`RWIl!jVMS z2AJ0}D;hLd*HT)+&z=N7`_W3D)))>g8nlSI*@F9Wy-S_u;JW_IE%ZDI?u+qkTA_?0 z{pg1|o(Sz|=WCflLtJZ2(R|fzU*u!E4zcs4E%{n^iiFD}G!cu&eOXQs={FR9xUckk zfyxV4;i)%(r-nl{L%YykjXPDc`7}j|QetDuGt88f^%1ISrsYr`n&dV#q)3N-iGbVH zNac?o_o%+tWGA+m)5MyzJ{C|58l$ojT~V1Csr5E*}X)Rrk~ z6;4Z(6S#|Od&)OooGxZ!7W(@5u^PN3%ENe*bn2%*n%~}QZl5B~i$JvE`FE#wl@nXg zKRNQm)ptSG*A{o4ZTW8`eQGSoRwn&MO_EKs@f1e`Fqmzg*>3pb| z7e|WB<`+eb%2WTja-LOtw&C)gQpsFmYE_AynRY`_f>h%i(Poei5mxy)Jf%n@l1yhH zT>lj45BMWDv@??ur2WlI1~Wa&u|PHNIT$4I*9Bav*%7Y)hvyTNMq!z{%k?j*cGF!V zXBxlizE$8N(>pdU>1H@Sn8#Wb57$vmlyzwJdNpkiqx`%t9Qt_ZTJRT6xf?vh`banw z7%CAt+NbB3X^h<`CrHH#i5uZABnh4r2`wgU*RcoR>sk`ex3S8S@JFcock*0yB8dw! zaVgRV5_40mW0q9wVq*=XM43+v)0Fu%sfBoiiv$QD8%d)`CATQDR!XkG5x&g z%bO`OQ|IFDo4z~pKAn{sAf_Ufk2@%}Nq2jqJ#t)RM&GHX6O!roGdFO`w|$S7Yx7=q zUUQ6@I(t?yutL$2^Ripzi|dLe0{lueGw zHQ;H6VIAN{It-)S(Hot2hNj$xBzKzBv5`|ajcGwxiz!ivO)j z=d+=~Xy$SEy=wC901mi_G)>#wFIO}GpFO{>V3o~7ytoN`epkO{ERQ+NDvu6jLcZsN z>13Zrt850XkPHqpxjQnG71@8Dos!~VEDIm3$j@z9FKNW7zS74S8-J3SQTiaU?(*a| z(Z1E9Em%K#X-Qh;L6pNOEAY=M1w&mjQ8pbU%C8TGFAytV#1}f%90QZ{x~(q|4&@!7 zJd^Uu+y-7W?mZ;!@nJSm4edudR-Bt;q)N;T&Y>?Ll0&u5jp}DR%9DH)6Zc>x2#4Md z(^^Li5mPSK4N8-g7S)Dp#nEo6?TnGaA#pI?SAPEt&k0&nHL*na>ADBsrMlocXrt_P z34ZRnWIuCVa$wp0W+~Q1(w8l5i)e#HNr3h|ZO|mDO=fA?{Z!)qUbaZz0%N223s?i_ zcwFngv4PfUh@y&OC4ZLXCw5G+fXf`{ZF9%CTOE*zxPV}iRt%cH~TD) zZg9o~xS)|K@Uco!_}hA_t(rtSV(HR%vH(0y3wO(g2JZ3d=(_SFiXK_WDtvgDrdeBD z0QFr(d)E|p%8c#XK+`#cgH?)wcVjGQ5?3x(VkVvTidB9KJ%pKRnizr>6`o4lK}Vbf zXKUzNWoT|AAG{-y?;Of)1k9A9=M(5CDtiVXBPxF!P~_+rh6vQ(hB6zCD2G*!4H+9L z+++P0<#6bC;T{?C@yrooOeHU7?ai~ZN=cZ>)QM|o`>90mqkdY~Uar^L5(8P4e6Rpq zd1lz-vq>hgA@zrbOgR>c0 zXK>Jpb%iLuxPm3vO#1Of&DC(NwF!YAWA{%(_w?1MHS~+?M+K~FH8w85LslkAa-Vgr z&ZY_2Dg_%Gpie&PwTo2h0C&@VBCDq`@3faN@2IRaOm}}WQa&9A=w-bopBeB5M>y2; z{tAU9RI*TtpW4HNayAZfSn<5Epu8BSc3-c>&eoz&oTe77ug1te_29c3(5j~}vil$t z8Damsr>|P&H^=&EYguL4AXCSA*t*j7y2v`J*}^It2DMnzzw>{!u~4KI!>_7Y#WQ$9 z&D+x;xjQwQdzaF0S4!Go9K&z5KfWcO;)<(_QWC9?QW95ND0XbLixe}~9NlER_C3{tC2TK^8{^cu*EY2ZD_`zW>yz0tm(K0x`B(7?JG zQ!3ux(Hp(@N+!&Yj|NHRiDp<9p~(|#Op&1>QO$9%T}PPpPCigjdB{Z+2AE@V^tK?@ zre5Itd8~!G4PL1T^5W9=pq8pZYRMz%$?defF9YW& zJwI_ZXiD>U4-WIKXq^~6*OLs zI5ko9k#)s8Kv$R72Rk;pdPr$UwV}yCxtC(XTZ&<#yuP1uyIjnmOZ6M7WmV)G8p5HAVaV*KmO5GGXg}|Xt__AJlz0^@EeFn^4KVlXYnYr= zSci#~TN;%DsC*J>g(V_4U^S#v6IspIYO-Sjn)|bBm???%*1YHd3w((oxK{dz(;}}-Nc77MdP%|ps7{;yPctc2czEB z%ZnxSt%jX&?d=mDGKt2i6r!~MZ9q5x@yQhkhlWfr+&*EYNi;+t=J&sL1)}i>2zG+- zFAy^$WvETCk)&thg1zJiUiaUy&lS?Smflb28r7lcx0Lf;E8bZ&F7pYxN3@OV$){9d z6MvG9M`TVscd{`{EC7xEN!5zs#^-$#BIEU>3oS?fX1arrvmN@<2?uk<)p zoXawv-}k=fBbivD@W%%~lfR)nWFzIy#QN`?aeTo&eH;5(<%>S8xDmZOtJdtf+eh1D z7pJXamACpH@svt?Jv*dsPrW=Bm>&V1;!s4|LrFDJo?e3-3C?Bh;$33$4WFN9t*r8F zAG?*S`>nGl5S8}Of@)?fi`9V2SClhTiYkH5$11<;W9zhH6t4M-+(&UttT#5SlNh>! zJn>^q{rR$qjnUb|Y@srs`B5tOecP8VU4(2i0(M=8Zzyy*oL-jfv##Fdne%jaGXegk(hgIesh|vCj$PKyzN(0V5N&}FVfQcGa@L>)< zWN4!6*gxnX;j=#3Oig?Wq`}B4}2YMwjP<^Mo+q#7>XFQvhA7S2lP`JbhSw z!xwIBNSrfKniv_Qj6TLh$2lG?9@humFR4r{z8qKaN7w?MRapn~0;k+L#6TM>bm{;z zqVF47i!=sn_gA1P2l{mcHllBEC2S+YTwFXPNX~O4Xjs5qB38Wz+`M@e-g8?0i9_97 zqSn1YwV1M@=fxAon&7K;)Gh|6wfCXC3+N+wK)yloYIzaRMu&3JyBuF+&LxwGa@%jxOdoMYVHX!w0?@;!74|Nk*Z9Wb&u&P~6{$;Zq%64yZPet+3Ztm7( zzg1VP#K*Xs-v|oa3^CngGS!i}s^(BkAJ;pwkL#Y;858H~jN@GMiaYb;IBSbaHgQ>8 zUtD)qCl|A#lOqiBuFe?F=Bf1aJ&qi-pH3;4Cbzz>xxR&SFAsT;=<*=T&sbDiks^=-ys`KnweL zWWP$u?Wfpal*;!AgT3YV|M+);Uv5L}>Ahm1l`3W*GC@?;8qr^mUXkF8^w|J}=2rTK3g)E4(HStLyEMD<14v zj{R!W3gsHMWBJx4iiO^PHn(H>Ldfe;o@!`tF6TwP*w>f}d3v2QEs!$XEG0D3Ro9sR zO7H|Ze17!g6Bd(aDD+~lRpNptu>YD^WR;Gn>rGzELddh!FQEo&#mxIoSUy-@bsznT zwydhRV|f%_TSRN7@U-rZh&J0>$l4{t0jhq zq(Wy#kK<0Jhs?`zJ%BRal*~Pj2j28-UY_KkmKUYzNVijC1-F}t+EV${IGgJ)GMgnd zqqNe$%Jrztcd2~^?%~n$Kl0G|@b^c`w=SQ%Y_B@sgim9{EUl-SXD5L){KTMLx~Hxa9w@w3$9vC(Art zPs^J=T%O`(F8xr}A(WNd0NyUvNk1>6GQ^9{3*{QW?^4y;RR0RaNOGID?tNbUiM`gh zaO?u-f|(21V)(H<56q>woSjvPPQ}iy^L+VBMtK5qx{SRlMLy=+EU}86v)e`m5&_No z6MM+oxMtSMSl6ShYUxO~H)*|EVrP^m!|nHGf|m~rosFzKA420hTK>H1A%mfJ!^A>! z2@x%LDC9Vh+wkXdZDF?f0-g?qa-j?^Q-w>4_T1pa(lKf zPjDwldU&O52gIF*TFKheUP`%yt8->)ttT9+8rr^`n35!yLf{KEf=hxg$*byIvR=Kz zPWc2eFb*Y;E#ck|=Tu;a_h`8WJ1%z^KtWG>EqdtI|LW;v5-($f%PH(bx!27RG~b+Bv*mYO+fB6crQr~B?s zv*$?SvuX@>R~8QBV0T2A7!2@xDw;MzW{lfT1WHA*B2xyNsLx%-E#?|si;2~}xO9za z&5`ay8dGDtL{@vck8q_Ae+nx_QPr0G(lz%+?sJ=N#OicNiWR*+PTHs5Z6Lofi!Vuh za16IIpJZ~UtgBtXnROMFc2_7oxhyLU{F-bE91|A7;1cG5?jxlaH0LSar5O$z>U##` z7p?2yztu%hm$sc<8ml63u7{(0x{)%`c1BstDN)XA zj@T=zqV|d^XqQhJ2Upknw6>A0jQK@JmSei_*N~wZF6G4UMJ7iF`$tq818&;0#P8*} zKJM~lXV9O~snvX4Ke&qWq%^bJW$}4(jCo2EJ3c6Lmo~3dF>4R`8mSgcEi3SYqjX83 zskPC)CI(bMl8kxO^83MRz3a%TsAYxPn^<^93c{i85#Wv#AKdE2-7`6E746lP@_u9o z7Yh6;pF7iMRaov2a?!FVybDk0+D^-%o)b4VV)x3#C^KODF#3$Jnhk~oa0*&)1;x=- zEcV>$Q`&?U{cK3oxox_*mJ=#pqA|?^marCSj-ozBkyWH6m+Oc3^=W+-4emA6=CMc@ zcfwM(u+h3ErC<>=x@4w87LT4=x@JlDI#7Q_Q=n!vWX*8sKI~p~)Fj@%aBM=JWsR@D zJ2;zJRY;VNZS_Ghfh+?*tyr?ijn zlm^Y3amBx6y6)l>;@Z6T!;|dlU4D$xGA7O*Ji_xdE6RURyZz*XO|f3IwyNt zX=2j|dM*SK)#-36%SwboL-pH&_o4RUJ8{MF9 z2j_k``{}Nltxni2eSk54!?x`?qJQ>O|WF_R9fQ*-|+UkGGBdQ5k&Wyu=qPrl^g4%znf z6fp~H(dfKz=ojIC&Mj->h0FjHFs&>Jn=5YG5Te^ z(l=ufm7oqu8|ePpdf3hB-txcLh!?I&gva~nz?ib4#d8`Lt~qj^Pnf3@T8JsiYjc|x zmd#sy*W%0aXz@7Yk#I-~E7(u_+aTTdjVIXS#@u`w{!3c;wHs{kW42L#0RLkfIA&zt zVoSy~Vhnl1P|7Zm4 zjU%xKg)zB+G#7R7}p{9X~RUDK!Y-v=JHX%3O7> z;lyKF=0rH;Z)VqM3+6KkCC~^G65xNc5L6|w3m=Y*2iox8xMG$s97_6O-y$4p39GW& z;9AW?GF3Q}&7r*QC6_iov_cUXDiu#3q&Yt5A&~0^p9dD-_!V9A_o>%<+JChk_s;{@ z`_$2f=+jiwdfWqZSgleusUuuHjs@0rrN2s2JnI8)}zcP&ocilh)A5!0ywD?9MymaMy4e1BC7T`U-t_6%~b-s>oVYAu5I4x-z51VpS zN}JTqDdRZCmhXo}*H3I010+icz_ynJ-G#jJh@;a*JdccOr*ewc*3o*T>j)PMYZuEF zcUE(=n>{&HqOj&IqLL$5`Uv*OAAu|wY5B85*41sgYg(RHDy#B~ZnYMdp3(0;xK-O@e8fNx5rXWt|L5m~KVNuR6L9~node?(Aw&`Ov86Lhbc_(lr z__FstE~(|Lx(Z(!b5DZTBsuEpnOcH*c2gC77B;_7R98>$O;u!K;;GF=jCu1M${jPs zVeU8>D(E{WnZO+vmFaz1u#cEEu`N#*eiY%Dsb!pR3;cASfL1uQ?XL*%l(k@XK97A?C7b_0^xW0`+<~QL`Xa8$m zdT@!>{@;Qtu$EkL8CKROk$*h07CgR+dGQVCR&+l<&C2!1)KKnBxhv((KXIoyiSlR_ z)(Gq=Ya-qTz>h?6c8%kPxRHShS`9y_hH1J7UKd=n?fG%;_DyD8L_FP!Y#7G%TU8+vsvTQXi#RMLdfmLDQ zpkT>}ynR^E1sR416z#gPqrP9as1ENJ19l_QLo$8hfFu$QZBXf(nW9i&QTWJPths%=)uIqYDsZtK`PTHblaS4t>iXR4Ub)< za-M4(*MOIEwKM!|9b?JptbI66lfj^Nn_KyJYM zDZsj5ak*)Y-CAAC^vGWAHT?$5t&wMTSXQ_?cOzRjUA(D?w(zC`$Xq4i5Z~{$OpCxU zb=2!I?Z!m{Q(F}%{3eR=Kw!FfJw`_9`%I>*-D7>eZ*rd=s+l3(kYdbx$GNllI&oaz zlj_XKyPc`wP+8xMr?=$2p$gvDzA+WekBq(n{N@kuM5Q7cIY?~3`zED8z({%eHuVz2 zw%{o4a1F`Qwq^Sku4XW%y2OR6p7>_rYSygEJNUJi0)LEy4ob3CbjPyMXhV`kqyD0C zUwq~%Xx$Zv*E=--l;^-dhUE+@!_)CSgDbZ|KfB#y7CG#2Y{}O^*Cf^sPbO^S519s_ z=`rwc2#2<)RF3I}JV(E)xZ)e(9Y4GWO|?m?FNZ_6{^+jc$T`quq%3g}N{#ASQO$Z7 z@*&8O10l;0F;o0Wsvw^CP_4THwxehrwmIh{0aC|D;j8OD#B9L`xYdVDabnhk1EGPz zhfHR~Gz^BGR>!!*CMvOAu18c-3@$w)E|F#;EkIg;R6;5ttwCCYbSKiCNIydQksh`} z41WI4QweTZ1%`q`OjId?BjyO#-8YJQ_WYM7}Qn6ipMJu{_R{h490vX;?hSE~hv zvP!y#P*$-+Evo1U5Uay{s-DR?q^2)Uv+Hb!)a037)nxXnaprC6$OI)oEK3XNhhKWdWmqK0-H6A`r8u|t99n?; zTzc<{;TzDw-MHmzSI73Mo zaiGa1*B2ed+&+r6a}pvz(@KnzDTidf4ga5F1-2~J6z5V6KXa+Zv|6VU$Z*5w-jq?8 zMxiDG3K6tI9-w9eY9gTGHUi4%PA=HGm{Qt8&s}9HMP_B~Omh#WYR~GKW+lwPN7lS> z@u;G$i>oYKu^ZAe6b^0eeF(dns$(GZr}v-(Ag)#awm{-=#l90mDq)kP^#3!YF}a9! z15Hu;M>~}(=mmbz*F4W? z_%dTp0631?&pgwR%w@Whm>{vE2-9__kAUu@>r#k)cDM}lh(Y&qdoKH zcrrZ0{jiG*J@88pmr4SnvZJ`5C8xuZsy1c7YG4;9;(m7cJz)EDIZga)#N#L&`a_u7 zUFjb3Kxj6+9H~DXojK3;3BF`IW=_F?ybtpR)-R7ob1L%v@YR{p zsQ2VF7NK-_?&MVDCwW5hLR=#-e|eGi>bgD}^|LL1AauOn?t|1{%pFUtXT8)i9rZ~R z8vgyc0DI~q;cL(ma6fxU&h(k#%LvOFb|{Cxp?-|rSNs?u(}e%&$2czQ56$qykT$@Z zdTTT1A*N_8|9oEiZ_j}blM&^P%X+DqNFRYaFtFQDU&;7=h?3g1K;?0k1L9`F%vQ5F z7rvv9sWd9d;J{uF<`6IDQlD-W(##k#o+wu2_~2YZl(CWA?~xm=B9?z{1}xn0rdI9X z77c2iy-vrSu#1x}>-7SGl6$ zNqBHy0~Rwb%s{8U{ljfz#0yUx2;s*Y6APreG}a z;WbZ0OL)45PD6Z3&`$1!N5QNdLSr6-tI1K-JC`UoApa5apUtJ72B0H&`|{#M`(WrL z_~&A+oqR$~p7%?{FyunR`zXu@*CRcO)PKb{;r-@J5i7t9tk9Fgp+A9xghP!39k9;x zXep=cMjSw2o1uwQF24^-HPbbnu?Tji%7vM|4{wLtZb#ecNOQ^`!y2&z_Gm6(-N58n z*U?xWL2JjGnjvni?o>FGGQ>&nrSLyv>-H~l5=3b*)_-`;M`}fsX&B$xMqxAs1G@v#OFhwnsy@(;Su7mHlnUsY?{qNI$j}XmebkrIK89V3ikQjVL_Z>RmPtV&F zzly!t7&qo_S*gzlYS9%X^?29n+(L7bSRI+2+~kUU)=lHYFXiLhm<2@m7O8VAjVXqm z{5E3iMU<^xG&C$}Ov32Xs9U}rIXB{l-N}t5DNHWfbkn5(Tk#z{TvD(%mQYEu`T~X& zy64X3As%Y_Ca1=a5^tli#>5s1B&JXF8oBd=co1Od}zP$=>ulWR*i@n4Jw+zux4ON8#oAb~C$$>f_W;2zHQ} zv2zg1(HJ{B_I7>oS#_d!A4Z3<+9G~VSZQV)bY42{n$>-5OMXz^55BqyXSUFbKmekt zt^pDb_Kg#OUryzQ%PoEm^iDF)sGdEe(NCg~^%+?@Ka<1OT45n)rk#Y<<9tW0%52-3 zb|9D$&u+fxClhWJ_lx_3x5XE<9thgvZ}J z;}Ko^f#9V0Y`n9_+XDp(Bd~SA`!2SYT02?;Zv|(;B1JC#&Knyv#TN9Cl6(3#^wBbe zX6=Ln!F%I->mAC=US@JZkGJ6CdSdxQdx63V1qv^mlnWF=_yYe1;kdm25?Pym?5&`k zYpaj3?Qf-J6f3c8Y;%F)71(~=jcmX62Kd(6-iSOIE8guaP-=vC z9zl-8WXx=K)R?QWY z;p2q)G?^&Q0i77%{#Ni_;BD>YWxEdqOXJT5PKwNg5x^k6obfE80gZ})K0Q~pM||?j z1Ht>^*Y+&g9V?=p1@UHmP^XX25_Z}YT})B}s{kzZIAuIJbzi^47i1xKp&2*Sk2a5V%nU-9YEvlF!`M8<>_y z##2b%ZC z`xlwoIT*ib`p5N@BDdr(5YNd+>i1vr7BjUe$5KS$O-+tIk9l#l5A-y~o|WZK4f64} zw%S=)r)Z2T?JL{H)YZ*OKc$Clh^af98sAsbjdP1?-)**acCFM{nH<_m0=j?0_gGp| z-d^Xv=I#_?H7YUj;{szv#FV_qpasltK7lrH&)C1qWWs6Lh*O@7%}kCg(;oA+%&nX9 z`8tb4uDcu;Q0JodPAS63{H66#`u;hXpuw>ocV z7IxVu95=E!lOnhIo=3~mHq7EMC&vTVhIlRTAHIzXTo=JK_tNoMv4NM=4Er=&W~&Cd zbbAt@gyzW;m}yoCRxsf0Mv?uBxz!%|!iqMkfjje>Wcp6Cc}qSmPqS4Q*p)`h)NH18 z!Je^|dug9Mc|x1~%nl;_0lH2dF4SZ&iIcO&Hq)A{IIZVdngX6&Z(EuRL7ev&y#0e17jU`%|{>F6Dg9_oX3=9$QNFac&-t4v$Kg4T}9HuKjq zGkI4qR{wE*hb#ocx%euAgZx>cS-5()k%{oexfYd+)ZcSaMIFSEVqYtGpM|kJqL!vH7#c0Z)$Z z{ocHb2DZOm-^sFuY%X9^5~$_3F9qX^(_g$oFqfs696iyV?ND}jvwIE|Wh;hQ`gKZV z?$>)$aKeSw|FYB3{h_xzh3gV@-Svx75pmZ4a{Ec}6|xrGLSNk3{=n}k*Ix0WAJ10k zn;qSUCgVyV^^W@IWZLgBSL?T;)gK6!#M7SU``-$#;7--YWEZu@*b1dR{JRa-Gf|qr-62?r_?0a( z9pel$rHv>@+LHfRyI}oT-Y?!FyTnuCeEiRqQ+mK%0?_{3*_^ieh4RdcS~jJVjlZqu z&fVR#3{Vi|W%@1+R+*QbmrlRz{H*zM3K>tw1^($$be_?2a{MWvZB3BXSf#k;N^?ns z`VNSr+w;X4v}7)&lZ(IXPXU+J1Q|djH`~l6GrqmY*gVNB%akV!mw0$q==2+10+&B) ze>1U;$)ntn4={CO@1rj~c>&rd>=D(CXeZ;paY|7B>6Gsw z$I%n?Xe7VkyG=zpoOh6{ki4{J-**l@liq;;;CF_;gn+s8%Lg@fyE#u``TkJmAjvp5 znpmKfK5+8`w|Jrv`TMRwvwzEj4F9eChi@H^@B1!4QUZG>PvQ9vJiDcQ-*+EIo+Y2S zrBJZOXE3J8-?ERJzS9Bv!^dfTd>iTG2KM0Fd-HI5-LY%h|M2bP@|^zyt!WvCeyuA` z!_4^Z*c4wz=Ra05IVpL+g$4T>F~iMueaO{*OCGm>r_=x8+p(zWFOfFzZS~*rk2BM} zc&-cb`m<`qCS2R*T`=f5?0l_&<*r5~o7z(8344ohzQDROMdAXHY?%ouyd`Y6&lAaJ zy~@OIK~z<&1sbjLNw`YfAj*(^!;#5S-+ zh^~Yl`9&L__iAd39JQ(YP{)N+pUG1p>vlz?5XEm6o#MH&p3(iG&rzBS+T=G8oyXod z6xuZ06T6|wRn`HEQ%SFB*^;tN&Ln?F+4E|?Ar%_z(epYBvD}riUd=bbnua(~s)14d zwYaw(RW1yZ_B$K86wO1g{9`U#MD%3`-@M94@63Rkc={@}n z{LjO78j;y0JIki{q8c@e(F=!)BBu(mSq$tZiw`o9^n-)+tS)+PB-LJt62@5yxef8~ zpRiRXDTDDbfx{SkqO3(MH`f;HW-Tcde7mg@k*p_aO}R}wbbWaLJ>Fk#g9X&`oqQ~r zqz7;r8id&%4-cyV^>rYbd>j1JpwT74JG>M&z+j+HJ_NY;a0#$;$l+~46IbFanJF}_ zM8BDLNXAkVd`a-Fu8o)=^WO1VoUXR9;e7!Rukr+goVZ%LR_ zdT}+u%Ec>Fu0+-HN^rlSi4ax@hZ*5*oQr9|d1(6Ccc@mA#Yg{{oAT&?4sYv0EJtc( zPU8;A+Q^!C1;fjZ;$?lwGNg_u(uUoYjL!`E>+1n;GUe z@sKSq!s^N^B`RNMo-xjLu9ew7U&YQrb6E)y*5dl|r$n&*%N281^!^Q`ix(2%Ib8pP zt9TI+f=I_9{Ufg1@a?~T_kWU?@h!<<(Mld83te;_S4Yn(;h^&jRxwss>-4M%eY0~) zKgM8b7-z{S55by9GJg?>ydj)26b4@GJDm5nLWWMKzLEIC!PNpU4zBL!MbQ$IDse*E z_@u^#7>lHenHLi|)~wz6N7V?+%$GwRnYQ8s*d%aXRTWo9?VDWfS)A_oSOx5tLz=ON zF7B(MFw}-Zly|D6v3w@E_*NA?8<5kFOh_iYIS+ei2Z!j_EO%Ds%`*!wNB+CJpr7-nDMw=g82)b1Ux@ByaBVHQ_{kW-J#5@;-@|< zPeI*_BJHTC8in)U9LoJww$bRhVWX2=ysrw@-L>T6k}8}*x92YLEyT!wgfB`Wt^H|L zdZRhwbu|vQ(G2+aW#ql>92KA~6}SzNUgE?gaE9z5P|FsQdFbLTRs0s_MY5H_Tw|tu zAwy1soX;tr4blJq8G<%%+vId8ELztZ!5;P>ff;iZ$=D^j+K1;pU1R9{*n?{yuJ@8i z`Y_#(XnZv7W?1z&<&B}I-P%oyq=SuT)wILV1;t^PSH9Ix6uoJ@0;!qBI=@>U5Pi1e-7SP<#@L2tI@NeG?L+^_~ z?}|Xb9)W%h(Cc&#QO5C z^a6O-75E1t@MPr+-%u`^3-~#0f36=psi>8SyMt6`ZshTPu=C%Efo zO%IHBZ*krbIIC{iLm_5$>h(AcO8Iy&3jgU~$*kLYX1{~^l=PEtqO)b}pyGQxZA5_1 zG3`#)9Gzp=4=y!DWXa-i=&2?;&r`WnTMYL833~a;ApL)J@F{19zZG(DV$MHjXW}3v zn%d|75tT&WgFR~p^v>aPmkFdttW)mz*(6hFHll5Zdq)(SJfPHGSl@g`Do;$&&vBWJ zQnm*tLtwSkv}Jls61B1pg|ZIhHWj116X3fCk+vdT72)UnY!mimZX3e)Io1fjrq7ca z;<0uRTl}e!ZdxV_o=R73x(3oS#bVqhk5L*54fZk?$WV+45LGIZ`5m-Z9r;$KWzafk zeXN^GHMES^_S5HM-H7gp^r8m#mb-gX3$^Hv1Uqx?ULztEIAuw%eJ}jAaC(mmQW&eG zsNC43w!}GQq76OX*vr4(knZD>QNL)Loj2^lu>#^dG3b^UI53fVP z|9B(LF@PPmQ1T+KVol$dGWL`(rolcM*=^)c<9`%?Ql@gxJ%drXCn+Ku8AK`#75UuK z24GGD>+D8Pl20gOmDGNM6HMqiQ^h@P53+@90jvBR`?zm|&wT{EMdh>|6Vr8xNd;G_e zKhr!pjB}1c#nqBGathtg%J|^K*twv)xqX_kiEY$3*sEviUUKrsIx1KCMl|9Z4edK) zt}EM;Pa&)Oz~3V}r1jTdJv+KSv3`Sdtba*4lQaKksrCDMrx;$OJ-1q)?2wXr+Sh9Q zvDvynlH!0hZG)Ae+N8rS4YTq|D$HL2zO#19J)evh zW6y=2$V1C&!7c;Upy<20$h*De+^I!4UwKRZ1-Y(_G1DA{zOmvP+E!@4E0k;bb~)5A z5_|nO>*(27KgIcU&-hBE?eI%6ayi&V+~IL!C*M>y6gtpLX^uT@0_DHlyW4p#!0l0R zx{>OtmPU%BL`o531qa%a->Vy&-$o`C!@u}umRRSj{5@pS)PNy}51L{i3w!vkYOX+B zxfth_^p-xeuXjACn}M`VN1sygR%dpgKm>)wu;6(GD6_ctt7omhE)WyzQ}K3e^GeJ` zh8yDo&+YA~Jm{OH7&Xxtl;4H5IO&JC9l<^myybN(7t=P)>dggy)ar*2C(Ud8pqp<0 zH}Xn&+fCly^O3f#5 zR%1$AS0(gvX5(J^B&qkjjFG!a?2E2TE9{>&97{DdqK7C?*~+ekRk0P`bR)7fffSwQ z1l3x<9y~9{W`V|)^mxucBBEiR8jLk7GU(gx!+vtL;t+O~!|rZe1ilinpaiCh*7kob zFBav+o^VF|2R?Qi|fby6SF%x>5>SW!(r>HZ7Ey zHl_J~@1#Y)Z`uFz&+|;q%$&=dIdd-Wc`v^g>jUXyP+PHXla4ScseNw+Qs?*%y!{jZ z-fz!Q8)+6FDyviGgqkq=Wby)*^@Yr~XP&0~4?=Q^{`*9D?9@Q6M9-uzZ;~5f~T1NPf1}3ET9CflCf6MWXaeN;Q_KQqpHZUu7saVo);6;pH-a1$|6raG#hT^|KJnZC$Mqy)RV#TGF zKlE*Bv3p$X886YkJKbA5@m;I`{kxi_ho534zrLL)21MQdD!xEvUM zpxR2Qr7m5?J6y+pPZ^0=mn;t_w$M50uZA^RDVG~N$&mC)=o4_w@?mQj2R#(tt1o!Q z0sf82sI;>BY*ZDW!Fv;Ma8tYedT5SCm;z`yHc>517JlpvBYZ!et9^~I*~arQ3%t?v z1F$>8npAfjqgw1%<_5pF5nq1KeThvkSAKZcNKi_R%9=!|U%MQQHSEm38g4qYKnNu` z?@!y+@mR=H_0d z)Q~mG%aMaKZ% zKGrK>st}HfhZn)IBAWwHqmP2tCjKiS0@TB1oMjl=Fzd4LJ^H8nw=>@Q9Qc78rEKQ$ z#bd%$gRs!^zS{;}-vdFD)7p{&O)jfq0Y=obtJN)TN11URnyL03gT_>fTLk{YF(Y~n zW)fSqV|fJ&yy_lt2J;E7RsuJ`0gUh(H%5f9+F@021Qsf@OmwIHifUms<{bMK9$_3p z4q?D|=PLT$}!A{{BcfIVi)vpcsDP{+*mfGT=TS8aQxZA}M&T$pD zL0i=4te5XGe(fQYoiDo?m)8};6%$6m+IsmHc3uA7Zk6FoH&YjM8PxU*HAZ{D#^@vSfz+H0e~6{dCe(?b}kDBAemr*v z{5$LJLU;%>U~1FZ|B&ylx}8J$w5NC0Ek}BKIyd{z{$+J9T+2<*zl?clG+T_(Li(jk zJ-2yu&;q|Iz1dINUcxy?Q%vUqaH!5VKrqs;oIsL)zUISkG86R%q@CKbh9!8Zla6 znR9_*42|$mHf)t=_3v4o282{lA*catzgCs5N%4s2cRNvD*}apn0^4A-&UAm5|6xq= z5CTJ8=zaMgZo`aYz*b9H^V8gxd#_(lb$6}qGr88au_Zi%e!V*7+B5yD@SK{)8XCWL zj16BfPh@F+FJUI!5dw~bjhkJA|1T99QeHss;1*KKOGJCh3r?!(t%J^cne}1s&ESQf zfE7T7_?-N@FBZh2EwAs>_*sNLxB)-g;<%qMf#e_fW%_q-Z0K=7y<3ytC<^ z{;ij|Y`nLLbWL?LepcAw!&(4DTA~>7r7&ZF;(i)fl2HwZnV3XYR193HO(;i~aicswP=|{O`4o`W97bXKB(|&)-0U!E47Sj#(>9j&!SH zCwY%_^Rb!u=b({u+?^>xAG)7)8&wu)@Tn8GJAhA=*ymH#jx;5>f9)W2hBRS+n^wqJ zd(mAbhHK8Ok*ArZvRd1Tw&AQOV>F~MezG{&oQA8N{gR&nEp5BIy@_hSAoMT48`rgN z>WfQE2`b;Pe00U7KjQmLe!=uyp~}l;KUcWH$1>LWC|>|Jr%S;74M~$j%=AZp zb=oQ=2TNb^zj7=^j-UI|#W>eVe+zWL7UTU*v-tD{ko~Iyqf}Gvd(!4o4%-Wbg$VC7 zMVKLZ-BDDRip2fZiXX*(vXZDhy!lB~7W zU~MQ{%`y&qnQ2Fn2RRdl>NCbiTz|rrq4>RC&U6v6QA1@$_~`CVugXOGVG~=0|6i~& zKO{KSY|UKpMD0gzYT@{z@cvLiFTKv*oOM@477P7S8|H&$Sal098n^2|leaI-YN1^_ z?Yz-*p14nBDH&Ug;@B?;{o&ptH?}+w=>4-~xe{>|C zT8L5id|!Bf+Z6iL|3}Ba+W)!DD09cTsVgdHfHR~$o`4l7^7lM5zS zqZX*q+g^*n&-);y7*yQf`wwFu^fdbIe?}i#=Gl%niEH63ZiJxGt|2tx+6bLXX=59q zwCgG`Q(TAQ^YrO$aoww-9k;cGuSRQdSEW(lQb2YwgbtqDN@I=Y&Y#=hhYG7uNXmz$ zyTWHublhoff^{Y#X#WHe(<|TaJ|b&P&h*?irpzf-l9aJF!d6^Bk{q)NLNx5pkILHntI! z7A*|5^>tQRnwhUOU6oeK%4#%?RwG(toAC`SEyFbL;x<<+;hSNdg??wMnK&Jq{Vb(V zdSXBg37ZPG{alo`p10)pEHQl|8yh}3ubchJd41!6)Ce^HT&z)1nh4KLSi!;^`23#Y zH1+Rkf3ZU|Pw11%25RIx+_8U+{SzI}f5)?TE#v1sj<7~vZqr$eDK+w42WhM>xIAWk z4fIV#q3qXKv(}fDIj(e;ovTsz-nqVU#fTE1tmUYC?Ta_d^IwKtnK>Fr2MZnf=)21X zh_4-zlEHCMLqg6{VM#D}$Uncp1S_xn0gdnm`gRg@TffJ?`Xu*_2NiKY@+D)ryfA z0*dF$N#lgg4pp~GHLAnTc#Fzb<~rVFa%nrE`)De0MOt*Ot*#GTuGYv~|KX3k^&1?W z{)=}(J4xn}fX{J%7~Se3@gwl8QG1w9M)(~LR_rRuLH#*voL6O?;1%DFutd2umJ-+E zisH3pu#(^E;w>M!?3Sptddt?e5uoCSQ+!%cyLPKfH53cmh_(On569J4eBcV_rkoVV zS-$eqo`5JXq6=xi{{*O9^`z7r76f>m4(;3>a$C3*m3cuRGN!?GZY>+xZ`rrD)3qRA zH0)ca0lon1T;VdWEnRC_S0hJuRzmM!^zj7&t>N4{W@*^)&j)Md1YAcLIv=V5s<~x- z>H3$~f3rSiL)ivDa3uCTc*8?09=c&;>Bcq4X*wQTP$Q=>|Hd^HHL}GG4PD*6flU!L z@liW43*=4_>M!uo5Mox9r$X4fS)&KfxjsVC!@g2Q&aMxM$p zqP%HHk&W0Ke@wSA_KJ`03`oZZzEx(^ zv$CyWi;xT?VR%Lf{Ov0EX@Px%>f~EGNCWjY;kBwGZF)$kJ~Te*sD-8$HQawf?7R=YN5bd7{mHqy>jU-QovWVV2*LBF0X$2Wj^ZC(oreuyVZJb*MbWlsTa$78*F>GSBi9Yr!yS>ZYccH`7*3XAfv?`7lkL? z4wU?WhhE4-s?l2EGSzXr z#OxMoNp2ANnFgHm1Yxzn!axKhPs$PAa`5j>60QJIjx1LDq@#*X(|1>CrkdIJ z5Aa4p(upCvp8;v*)gSGCSYY{)5b5a5XW$8GgfduZsC||#*x^sJRENE$`~kAvh|>d7 z@l__Ot+3IsUh>)<%nI)>mU5@1y31b!-T}$KS_bvS{1y%#I3R7UCcaia+Ta`HCo2sd zEG#F%N`tQ^J4ea`JZH=u@dEU$GtygFVv=n@st?Au7+a^LU-H3@raPYJZh}?Kl#wkA zx$}QvypF+#(aHyEpE46lq&NCp*237}2 zJOkBpJe7pBoG&_yXvUlPjlWU3Zg5@!O@lq9^_+M5wKOc%<~(~Xg@mtfRDX{D(dxhZ zRaLye+4P<%kVwVDB1Bb1@8v3z!BJ5Q3AoaE)8~z{0f#EkEtf&oAb2fKYsom#B2uiw z$0kk|@}SSQ2K+8_>3i_52n)t?xpna&u6r!ICm9sp-ykEHaulOf>w64Oit)|^pLc|C z&Tqz*%KKd5l~23cSqhb)7odBNv2rNH3#@9X=Pz5xs-8zJo}^uM$~VAb94CB$e>#|n zX6d~XAw?MtoW2!eTmj3FJIb6+k)(@v zu(BoLwg1Ex6*z^lY?L>yqSEsh zSV`{^S9nIi>qeBf10$F?Uj~KqwI-lpWIboVKl&Bz^A0`>KT#}gxp!nh8w*-Z%kAf$ z0c!DX@a7-ZJ|Eu(`~U6eb53BjulnS?dKEN%;O}c(hw68?p@)T}7)K1XG~9T-X>l12~p!)CK|CC_W|WZhZ#Oz@nQ8R*d-bS?4r|_ zcvI3BwVxRJYEeGELJ!@n<(1%XSRGh9%$Q--3%H+Gid59Eoy zkNuGrpwL_VewF20KW{nb*I2#=P4|_5*A^~&SM_=S<|GC#`LHiRSMz(~XXn|^yRP-L zjEcm{eDpHvoA*HTV?a6#-9;DBEvZ+jg&uzcc!AK91Z6WI?UT=gW(efN+rhyt!dQW& z7yG>6kra@JwuQr`ntXd;-;+_XyD|f_?Bi;a5Jj`==9}PkjY{29$e&@EmpV2$yZspz z+-r0<+-k7-&iR)g`)L0j$6IZ0h@%9^?-z!ohJk3$p2ApQuIOAJ;Ld2zfi2v$1Jxm^ zd4Nqh<)!(Z^?e2^;Q^rXbLob*0+GhRJCI;Mj_(yK4A*U(FQdY8=*)ei4lS?b4{@*2 zXi_IbOJ(t>=oDN+omNI zz(*NR9`aT>%StUP_R0nB_s(lA21|`B*nsSV6#&wEYPl!4SIL6<6?jY2p{6^;1`nZ} zY=bWg%v%~Z<${-4W;^}<`6l2{ZVv)~Q7u?$h0_F3H%{||KT^@i00rNt0o`T-g?c>n zjUPBYQ%gKa&V|B_Z0h4FausUT5D z^yO%_n~9kt67^!Kr?(I;j05)Uz^yAkjqmd<*4D6egM89J?-4mQiWkF5XeU9>7x7{L zTMMx+zfS((IvVk98CJ*$KgH$`L)~9p^f?+atNfLxrzk}j*urxmeE)pI7@dzQvKVQU68l-px47vISaR) z+pm2tOjD=|Fuw!O%QDd5i0Hsf=_rGh_+nU&Vnv=t^g~ce#C)lPPM3ODy|YJ|S5AdQ z&%r)}J;(Fz7DvFSdbgUe`5?D|C9_E&I+0@%QmWCT?C3B3p$7a*D2HkklzNU)+6w4a ztA;e7Ax}|c(}aDnLu8&*o2!Vh>0=c?9BScEpUK41^=A_v9&4upLBMRvq1BC zqrOuMpICj;=YuK>?5MrG*}Ty##worgs0_ll&uz}fI=#Gw7kM)`F<~RLnCA{iyJW)g zw!muzo7k&hfd`u7ZUqMMeAT3MP%3dP7H63=&^keU%Tq5KkB@k?uF%kan+Pv8DYvyO zc5Uk^lyk9DW$yJahPR9`HaI;${9c)OtMEPYEn)G*iwFDN z0ed9S8L$(jx^j?e4W}V}KJugI^7Nr!HF&zV5;sqk5#fDJ+zk7F9z5VefV1pB22MVefmL9`IG0Sh}iK)g1!&M&%~tP0LDV z8ukLhET)wj@PNx|`lNS5@Y=;dGlO!zh%Y=^!D6I3(|0ER)rTQ|e7~3aT9{VXLOU%e zJr%amhXnvL4WOqpYYypdU59JN*A`s~txE(4P~!{NU`^mjmfOnLk~ETc!>>g| z62^2)NE>@fmfpj9s5YCx zx_K<+V6f+sDj3IDJ*3R*m*#WZX-9N%$XXeGOB}KAfe;HH2vmnU#Ro(b=7`;cskoy~ zvD9G~R0E`?jeU~kDwpyd_~GMZ9@mJOZK)wl$Kf%eLEp1^_)R=42acl`t^qYU+!tNY zl)C;`>ysV;^7s!;4Ib4d1N@t08-vnC#d{vfp0hD7`TnoBLe>TBAd+^;Qrj^?pjAq5 z4f~1t&(FnboM!-qw*!7DnDu8~mOkIh(&qgKZJT^C3S;GwfeCZDoYl@4@lRO0ld<;< zO1BTDcG^%IW_di%)?O>}1>v)2#OEE2T^zr+ zi&yXIQghEZ^}fitL`T^BUw4M}cobhE)%?6P+@0M|zC1^>UVqp}PBipm^WkHMP2^_n za$+t4%?Nvhv$P`(N?C&z#RE^Z;(;e$EOZ`+gs)4<3m!1!DfGUxy$*2#EHh>fdszNI z{uIBGSE4^$X=<05J19LrNZ2COKXPSbcT}ue(E5lIO42BW)3Eso(2Vp3s($3KaXW4l z8oP9=?T#ngjwdjay?_P$eUyW=MbiL2s6EZi*cbPVr-H=s4 z>a?m4_zuKZy^(y-f^Le258))5Z>}RJh=7c%Pf88u+94H?xa|!dZoe$OJV@Mc8GOv~ zo_y$qY!)k>+J|LH933p9$y&a-1odDIwE@Q=aUWnJBgLj5WA$vd&HBAFZLY}CUw5#2%g-X*d+MQt4xnM^_~wzuk(dM8a+b0Ud$CvCgd0BofaU>5dE~m zi6@#=I7`U?5NAQDE(l}{Sk1E7MDJoDvP;X_v2T0EIl|K}8%%$3n#GqK2?b{7x1qm2J5BTv0dXImXP$vA| zZ^k~uQ9v4RW~}b?<~+{hs2;YX{&1ObDDw+gMg*nYAnkcUPX;$*MBZ|__)SP4QMM%A z9!gVU?g-BD2M!y=DA;;NkE;+rj2QP>{Ibu_tHxRjT7Yo$gZPPaytp$yY1tbI6ANBk zIM12jED(1uRl}1mNF=S6?uXxJ`o zX1~2s*GiZ?d`q#D(0F)-Hw&NUK=#=MouQ!g)!PZ8%1PKZq3^M3tlK`chD144B}?yl&(JRZ1i3=CzOgHmI5!53gPk^Nz=(t#}$s;HUMQkXph0ML!?z_c~#!r#P9j z)`7<`nqdcoRU+mv-^>r~rCDIStRggxF4{R84(s6$XUoC09*%bB0aIVpYxE^*mB^@D*QCxao0NllG2S=f=M<6x#ETuPN*Qweclx`T*yu{6*F?$*-rxWF6!w!T6 zB$?Yq79l}t%-~JVXzXW5_rBi`8_*Q&n~tmpk7bO&ZQp)~@M_Yb%R9a*D~t1HWQ~Lk z4OdUNIouBLMCGikSl_{Jwm{b&l(K_n3t3^phN_cI{NCROx@Sp?v6DD~LCK=Tu0iZg zp6S4k0{<`bHMBm~R3};D(Ju1wgQOb_-NxzMX|JDD$uVNS{ORk~QU|Z>57x_CcDhQD#+jP?N*K zYMiSFjgVNrEIY0O}C&y=8P%I;%*=zn5^dI;RLIIGAo`Y|qQP6kM zpJf$hA-+J8-niN&rdO~OOF@^@w}kdh5x@}UWw z3TIMz;*cgaE$$3mM`m1VcUm=Pe~uJ-q_~6s!EeX)3|y;lJ(K?y((-t4Bwe6^HR5FG z#M#h772wUvzDZ~u+SvuAmGCtllr~{UXar_%P_irNU)(&{%mEwkA6Q?B&Z$K&Rl|GY zL?Nvz6D9dPcFfobisp4%)fC*hQMogM?s%~yc1;l`duBTM&XJx`BFp>+-<7z$2JFCq z(^Ex!*(V*4_@>J~vgFVU&_o--0#7Sew1nt%BRC&sS(U~6h*o2Pv2r%n;suwh*Ak@$ z8O0G@b5NQyz(ifE$*S>2=BhF3!@6^{W6>k+lWXC#`3N)Hdq$(|(j$T9Cq$ADfC3iT zl-s?tD^9f7d!nbk=!ibk49-(b$1A;g4@PF`!4c8~(j%4M81p21Pwe6s9hr)LTtp{y z=`zlFv%yUv&C@TvBsH*zGd$Vw@Rc91^Vs(}FZ(Sx>jU;c{$+PrFG35#ZvQZ!vE4fr z^Rv>^@h;g%W~0o%d8y=&z1(Z|9>Z;lR<+gJ(TctFH223?<#p^sf6U>H%@J>KuVQ_y zWWO1dmSJBGyj1AZ5NG!3YdeUPzG0pk(I_s3PZ-8*`p{!+(YchF6Z_s?@YVY|)bK1# zv=?-`VF7z?h(q__QWru4Z{OFS5WF zEpK$|3=f=F|COahcCd_u4)TwFR#tan|8F65GrNOuI#@;`VpjYlCVYR9qpT~RcNK+0 z@Xr1%#gB3MKZzU8x42~<>KCpRYBV)mtGXX+6|nv!7p-FNKKr{LqAK&g9}C2QsO2|Y z)K(t7_SGRV=fvK#$Md6r}3@$i(~W)%uxas$iw(5(!Cgi@kPjL z^L)<b+0T?<=QWB_PvR~o%DQWSELI0#0T5z(6mQ;z*FZ~icaYDAL`%S z&C&$lA&2VI$6(*u>#j*y)y1ng6L^zZ-+Ga<2;M8x?SXpt9#CVbcM<9hgxy0y=}JU! zjLia{k1Rh%sku(6xfXaYs*^iVn%6A|;aW?9h@o1?1li!eLP{B~wd&-)LIy4Rcwui> z40J}d_E-Gxbekf!+RgnD1M@HN25mn#XzGu+JgGn8Qo)57HS6bO)B|leYVM(6V3698 z1(T=Ey}(mF`gRto`njGcr7kf*@o)zocke8;_dMqQeYYy6tN`{4k$an3f`Lmc7`LK{dZoe=G( z{8@hL)1>EMY_^#q=gZQkutj8L6HLI%%aNszug*5f(ud%H(Di%rsT^=x6bxACNSj#T ztv)SqUViE75SQjd>!T0jAD+r}m=RmaUT;Y5`8n>l0%d{txU{RK_-BA=8cSHvsS3vv zA)POZ2!77srNXFOnFIS5nJ*i04Zbn-R5HVNFT0gHs5!7`84Gc`X4KhGgvnCCeU>9hOE zLJ9BQjpy{j_CMfxdvk=w_v3Zf+eG=&5&C|Z&&G`GE^|qs8NQ@S-n|s19ch?Qd$)MZ zk@U+9@9(x811E}0HB8h5)zj`4lYW`k!}GfwCamW@*x|S~4d-<{0nd+IJ+~<+3LPT3PDn{$;7>{Yz8*{-38pt|0(5@BVN7 z@sJBpeU9Rrptmh#y-ypxGWiojeXT0!!>GNee~PMDmRgUp6t1}6KOs`hX5-+jpstaE zM+%C6<0$uk;^C1V@ljq~Yb4@dyz0iTF9N7>^etrRH%B$N`>b+Tg}a2yJzO^7eQv&_ zt2Gu4g7)k*FSyKXE+A6Z&dIqo|FVmJ7iZZe)8>6DyL0*8O>unhqlYcLmtAWWV z^%3R2YJf9ck$Pc6k@>(Cse3TJ+GID<6`*z zBMwF!Y~WP7y*TdvFU_CG)>?x#dJGQY<1Wpoo@xqgvM(*AvHBVEs**J&n&MGyT#7D5 z1!VkjPIbx^>A7PRhdo3m>9%miSEQ}SSQ}k4Gnb+Uj`9`hu|X=0nRk_vjseA~hSENG zEv-t)`@qn(+8U+^;!e?;yVI%auFcLD?{vC~ zEZn_?DnVbo8Q8PfarC<5>K*!15yjQwGY-uuuGc-{8OIJ#A>lCxpU8OkQ}q6a4T4=9 z0Uc;l0ZC4;NV;R-+VFca*5F_zs`a$ldULQ#sa$D^s z^TGEdey#>G2H1B)Vxm@LCwqa@{jow{lU8{@b{vqqAk|W&dJU;GN~%8t6?9NK@{@GH zOTLBX75z!p>t=TBH=YUc6>jk#39PHYXdG%YN~LR#K1t{-(BB45G*`vhLTQ9~_m~4X zKLSZoqrrVAU-z+Al(h<|>lXx}RKXv<7d07_RsmUOky4K>A!sF87XtkOo@hd9%PfIf zVRfiWTyWX7!jN(QBn^f>=t+_m-MjA1;vvu%$K0=tqh7HK=SSRw zQWxY_HDj@_QlT{|?f^z&Xc{w*Qm*!5&Y*knQi6TfptLKfpm;s4 zgC*#j)FPUTv@^e!zHTsEyaP4e<(TGMhqEM{P4+e6EFNcRz8;*7!da>>yW$Sic$Z^> zZynAII7{#~;Y^3K(Y_v>sc~k6UYluVxR!dKX~r)K|Lpte^OisllxjiNE^5si_>X44 zr};WXQ{s~iS*pvOE8^hW(J+VJe-LvWNHvYs9KyV$X)`u!=F|I0u!*xW!dO<7lsS#9 z-;q8N@O>DNzfERcGfDHN4w!(>z!dxcYz$BB4Fi6V--4S3nRP{R*mnjczOsGEReenJblgrqOHETB9zov9$`MP@^D6Lq{@?0**x{B5J z-tJ-*>()-eanFOR%d1@FWgE&@R;*u#EbGhHm91GlYnG{S(V_*5W|{KtUsqnb@?jHh zu2z!ihm)8VmET*jenUAGXv#0hpOTk`MMvI4izSpR@`5{(zIcX zsSKrVC^u~o%l|EF`9l?D<+Dr^SN@oN@q=Y$_GHCwne$1(q*sgtM9oNT+dH221pH{LjP+Kd$}lU>UJ zu|H*Aji+6^iFcd0k`ZIp#CRgZEdmiR-6KT+gOl%d*&( zIeq2~+fZq!3d*pt#Y=9TmVHb37rrQ-xjg65>33JLxhwB4H!Ue$Um4yG;-6%)975vf zYkm^Gj%!Lp@Tq3; zP(KtOiEGLiHFOOhMo(QI)>%ZujmO^6; zi$F-cZyjAfH-beXbe=R+LkZb^-`Oc0t34DB?VG|On>!SavhUhSzm{7b8TI?3uYXx{OIChT z*Ecf~ZkbhQ`{t>K3vWKU<wm#?8*vO@KQeUwj+5!i?`68`d(hujgyYATGu>}W!{<{f z(ARL}<0xDYd|iZ8#_h1#87|8YTRJ)~Lfk9&1GlXb7`&^QZYRQe+}n&}B)WwPA7aJS z62@^H4BkWEZ+nR8=%Bp+H56`fGu;iFFiw6IzF&#+TZhgm9sOtzpu#^o*TG4%A`c$? zA+(7LNBw{NXL1Gl@Vr93-WA1CGhbGob^US7hwDN8dODRJb3+6(a`wnaBbgpY7|Svg za^r&)gNCPi&^=1}(;wZxi)j3zUkeS!p + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The AirBrainH743 board provides the following clock sources: + * + * X1: 8 MHz crystal for HSE + */ + +#define STM32_BOARD_XTAL 8000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 8,000,000 + * + * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * + * SYSCLK = PLL_VCO / PLLP + * CPUCLK = SYSCLK / D1CPRE + */ + +#define STM32_BOARD_USEHSE + +#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE + +/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (8,000,000 / 1) * 120 = 960 MHz + * + * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz + * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz + */ + +#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP1EN | \ + RCC_PLLCFGR_DIVQ1EN | \ + RCC_PLLCFGR_DIVR1EN) +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(120) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(5) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) + +#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 120) +#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 5) +#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) + +/* PLL2 */ + +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2) + +/* PLL3 */ + +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL3RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ3EN) +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(2) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2) + +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2) + +/* SYSCLK = PLL1P = 480MHz + * CPUCLK = SYSCLK / 1 = 480 MHz + */ + +#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) +#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) +#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) + +/* Configure Clock Assignments */ + +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) + * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240 + */ + +#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ +#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */ +#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB4 clock (PCLK4) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */ +#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timer clock frequencies */ + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* Kernel Clock Configuration */ + +/* I2C123 clock source */ + +#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI + +/* I2C4 clock source */ + +#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI + +/* SPI123 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 + +/* SPI45 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 + +/* SPI6 clock source */ + +#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 + +/* USB 1 and 2 clock source */ + +#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 + +/* ADC 1 2 3 clock source */ + +#define STM32_RCC_D3CCIPR_ADCSRC RCC_D3CCIPR_ADCSEL_PLL2 + +/* FDCAN 1 clock source */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE +#define STM32_FDCANCLK STM32_HSE_FREQUENCY + +/* FLASH wait states */ + +#define BOARD_FLASH_WAITSTATES 2 + +/* LED definitions ******************************************************************/ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Alternate function pin selections ************************************************/ + +/* USART1 - Debug (PA9 TX, PA10 RX) */ +#define GPIO_USART1_RX GPIO_USART1_RX_2 /* PA10 */ +#define GPIO_USART1_TX GPIO_USART1_TX_2 /* PA9 */ + +/* USART2 - RC input (PD5 TX, PD6 RX) */ +#define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */ +#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ + +/* USART3 - DJI/MSP (PD8 TX, PD9 RX) */ +#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ + +/* UART4 - General (PB9 TX, PB8 RX) */ +#define GPIO_UART4_RX GPIO_UART4_RX_3 /* PB8 */ +#define GPIO_UART4_TX GPIO_UART4_TX_3 /* PB9 */ + +/* UART5 - Companion (PB13 TX, PB12 RX) */ +#define GPIO_UART5_RX GPIO_UART5_RX_1 /* PB12 */ +#define GPIO_UART5_TX GPIO_UART5_TX_1 /* PB13 */ + +/* UART7 - ESC telemetry (PE8 TX, PE7 RX) */ +#define GPIO_UART7_RX GPIO_UART7_RX_3 /* PE7 */ +#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */ + +/* UART8 - GPS (PE1 TX, PE0 RX) */ +#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */ +#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */ + + +/* SPI + * + * SPI1: IMU (PA5 SCK, PA6 MISO, PA7 MOSI) + * SPI2: W25N Flash (PD3 SCK, PB14 MISO, PC3 MOSI) + * SPI4: External (PE12 SCK, PE5 MISO, PE6 MOSI) + */ + +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 /* PA6 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1 /* PA7 */ +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 /* PA5 */ + +#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1 /* PB14 */ +#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_3 /* PC3 */ +#define GPIO_SPI2_SCK GPIO_SPI2_SCK_5 /* PD3 */ + +#define GPIO_SPI4_MISO GPIO_SPI4_MISO_2 /* PE5 */ +#define GPIO_SPI4_MOSI GPIO_SPI4_MOSI_2 /* PE6 */ +#define GPIO_SPI4_SCK GPIO_SPI4_SCK_1 /* PE12 */ + +/* I2C + * + * I2C1: Internal (PB6 SCL, PB7 SDA) + */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 /* PB6 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 /* PB7 */ + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN7) + + +/* USB + * + * OTG_FS_DM PA11 + * OTG_FS_DP PA12 + * VBUS PD0 + */ + + +#endif /*__NUTTX_CONFIG_AIRBRAINH743_INCLUDE_BOARD_H */ diff --git a/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h b/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..2bd6646a83 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +/* DMA mapping for SPI1 (IMU) */ +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* DMA1:37 */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* DMA1:38 */ + +/* DMA mapping for SPI2 (W25N Flash) */ +#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* DMA1:39 */ +#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* DMA1:40 */ diff --git a/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..56f41becc6 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig @@ -0,0 +1,257 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PRINTF is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_SPI_CALLBACK is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/gearup/airbrainh743/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=512 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0050 +CONFIG_CDCACM_PRODUCTSTR="AirBrainH743" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x3162 +CONFIG_CDCACM_VENDORSTR="Gear Up" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_READ_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=1 +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MM_REGIONS=4 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_PROGMEM=y +CONFIG_MTD_W25N=y +CONFIG_W25N_SPIFREQUENCY=104000000 +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SCHED_WAITPID=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC3=y +CONFIG_STM32H7_BBSRAM=y +CONFIG_STM32H7_BBSRAM_FILES=5 +CONFIG_STM32H7_BDMA=y +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_DMAMUX1=y +CONFIG_STM32H7_FLOWCONTROL_BROKEN=y +CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C_DYNTIMEO=y +CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_RTC_HSECLOCK=y +CONFIG_STM32H7_RTC_MAGIC_REG=1 +CONFIG_STM32H7_SAVE_CRASHDUMP=y +CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI2=y +CONFIG_STM32H7_SPI2_DMA=y +CONFIG_STM32H7_SPI2_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI4=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM2=y +CONFIG_STM32H7_TIM3=y +CONFIG_STM32H7_TIM5=y +CONFIG_STM32H7_TIM8=y +CONFIG_STM32H7_UART4=y +CONFIG_STM32H7_UART5=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_UART8=y +CONFIG_STM32H7_USART1=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_STM32H7_USART_BREAKS=y +CONFIG_STM32H7_USART_INVERT=y +CONFIG_STM32H7_USART_SINGLEWIRE=y +CONFIG_STM32H7_USART_SWAP=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGTSTP=y +CONFIG_UART4_BAUD=57600 +CONFIG_UART4_RXBUFSIZE=600 +CONFIG_UART4_TXBUFSIZE=1500 +CONFIG_UART5_BAUD=57600 +CONFIG_UART5_RXBUFSIZE=600 +CONFIG_UART5_TXBUFSIZE=1500 +CONFIG_UART7_BAUD=57600 +CONFIG_UART7_RXBUFSIZE=600 +CONFIG_UART7_TXBUFSIZE=1500 +CONFIG_UART8_BAUD=57600 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_TXBUFSIZE=1500 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_SERIAL_CONSOLE=y +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_TXBUFSIZE=1500 +CONFIG_USART3_BAUD=57600 +CONFIG_USART3_RXBUFSIZE=600 +CONFIG_USART3_TXBUFSIZE=1500 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y diff --git a/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld b/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..fb877cc443 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,213 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The Durandal-v1 uses an STM32H743II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The Durandal has a Switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the swiutch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K + sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K + sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K + sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K + sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K + bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld b/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..a01eb2e2a8 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld @@ -0,0 +1,228 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The board uses an STM32H743II and has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * There's a switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the switch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1792K /* params in last sector */ + + DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */ + SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */ + SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */ + BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + + /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */ + . = ALIGN(16); + FILL(0xffff) + . += 16; + } > AXI_SRAM AT > FLASH = 0xffff + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > AXI_SRAM + + /* Emit the the D3 power domain section for locating BDMA data */ + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > SRAM4 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/gearup/airbrainh743/src/CMakeLists.txt b/boards/gearup/airbrainh743/src/CMakeLists.txt new file mode 100644 index 0000000000..63d047cdea --- /dev/null +++ b/boards/gearup/airbrainh743/src/CMakeLists.txt @@ -0,0 +1,67 @@ +############################################################################ +# +# Copyright (c) 2026 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_library(drivers_board + bootloader_main.c + usb.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + add_library(drivers_board + i2c.cpp + init.c + led.c + spi.cpp + timer_config.cpp + usb.c + ) + add_dependencies(drivers_board arch_board_hw_info) + + target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/gearup/airbrainh743/src/board_config.h b/boards/gearup/airbrainh743/src/board_config.h new file mode 100644 index 0000000000..1515f395ad --- /dev/null +++ b/boards/gearup/airbrainh743/src/board_config.h @@ -0,0 +1,216 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * AirBrainH743 (Gear Up) internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +/* Enable small flash logging support (for W25N NAND flash) */ +#ifdef CONFIG_MTD_W25N +# define BOARD_SMALL_FLASH_LOGGING 1 +#endif + +/* LEDs are active low + * STAT RGB LED: + * PB15 = Blue + * PD11 = Green + * PD15 = Red + * BAT LED (orange): hardwired to power input + */ +#define GPIO_nLED_BLUE /* PB15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN15) +#define GPIO_nLED_GREEN /* PD11 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN11) +#define GPIO_nLED_RED /* PD15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN15) + +#define BOARD_HAS_CONTROL_STATUS_LEDS 1 +#define BOARD_OVERLOAD_LED LED_RED +#define BOARD_ARMED_STATE_LED LED_GREEN + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ +#define ADC1_CH(n) (n) + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ +#define PX4_ADC_GPIO \ + /* PC4 */ GPIO_ADC12_INP4, \ + /* PC5 */ GPIO_ADC12_INP8 + +/* Define Channel numbers must match above GPIO pin IN(n)*/ +#define ADC_BATTERY_VOLTAGE_CHANNEL /* PC4 */ ADC1_CH(4) +#define ADC_BATTERY_CURRENT_CHANNEL /* PC5 */ ADC1_CH(8) + +#define ADC_CHANNELS \ + ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \ + (1 << ADC_BATTERY_CURRENT_CHANNEL)) + + +/* Define Battery Voltage Divider and A per V + */ +#define BOARD_BATTERY1_V_DIV (15.0f) +#define BOARD_BATTERY1_A_PER_V (101.0f) + + +/* PWM + * 8 PWM outputs for motors + 1 for LED strip + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 9 +#define DIRECT_INPUT_TIMER_CHANNELS 9 + +#define BOARD_HAS_PWM DIRECT_PWM_OUTPUT_CHANNELS + + +/* Tone alarm output - PA15 */ +#define GPIO_TONE_ALARM_IDLE /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TONE_ALARM_GPIO /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) + + +/* ICM42688P FSYNC - directly connected to IMU via GPIO (no timer). + * The driver clears TMST_FSYNC_EN and FIFO_TMST_FSYNC_EN, so FSYNC is unused. + * This GPIO is kept low to prevent spurious triggers. + */ +#define GPIO_42688P_FSYNC /* PC7 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN7) + + +/* USB OTG FS + * + * PD0 VBUS sensing (active high input) + */ +#define GPIO_OTGFS_VBUS /* PD0 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN0) + + +/* High-resolution timer */ +#define HRT_TIMER 8 /* use timer8 for the HRT */ +#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ + + +/* + * Serial Port Mapping: + * + * UART Device Pins Function + * ---- ------ ---- -------- + * USART1 /dev/ttyS0 PA9/PA10 Console/Debug + * USART2 /dev/ttyS1 PD5/PD6 RC Input + * USART3 /dev/ttyS2 PD8/PD9 TEL4 (DJI/MSP) + * UART4 /dev/ttyS3 PA0/PA1 TEL1 + * UART5 /dev/ttyS4 PB13/PB12 TEL2 + * UART7 /dev/ttyS5 PE8/PE7 TEL3 (ESC Telemetry) + * UART8 /dev/ttyS6 PE1/PE0 GPS1 + */ + +/* RC Serial port - USART2 (PD5/PD6) */ +#define RC_SERIAL_PORT "/dev/ttyS1" +#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT + + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ +#define BOARD_HAS_ON_RESET 1 + + +#define PX4_GPIO_INIT_LIST { \ + PX4_ADC_GPIO, \ + GPIO_nLED_RED, \ + GPIO_nLED_GREEN, \ + GPIO_nLED_BLUE, \ + GPIO_TONE_ALARM_IDLE, \ + GPIO_42688P_FSYNC, \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +#define BOARD_NUM_IO_TIMERS 4 + + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the board. + * + ****************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +/* Parameters stored in internal flash */ +#define FLASH_BASED_PARAMS + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/gearup/airbrainh743/src/bootloader_main.c b/boards/gearup/airbrainh743/src/bootloader_main.c new file mode 100644 index 0000000000..996370b00e --- /dev/null +++ b/boards/gearup/airbrainh743/src/bootloader_main.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * AirBrainH743-specific early startup code for bootloader + */ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +__EXPORT void board_on_reset(int status) {} + +__EXPORT void stm32_boardinitialize(void) +{ + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + return 0; +} + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/gearup/airbrainh743/src/hw_config.h b/boards/gearup/airbrainh743/src/hw_config.h new file mode 100644 index 0000000000..38e16b4059 --- /dev/null +++ b/boards/gearup/airbrainh743/src/hw_config.h @@ -0,0 +1,85 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#define APP_LOAD_ADDRESS 0x08020000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" +#define BOARD_VBUS MK_GPIO_INPUT(GPIO_OTGFS_VBUS) + +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,57600" +#define BOOT_DELAY_ADDRESS 0x000001a0 +#define BOARD_TYPE 1209 +#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880) +#define BOARD_FLASH_SECTORS (14) +#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024) + +#define OSC_FREQ 8 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +/* Reserve 128KB (1 sector) at end of flash for parameters */ +#define APP_RESERVATION_SIZE (1 * 128 * 1024) + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 diff --git a/boards/gearup/airbrainh743/src/i2c.cpp b/boards/gearup/airbrainh743/src/i2c.cpp new file mode 100644 index 0000000000..9bb4992776 --- /dev/null +++ b/boards/gearup/airbrainh743/src/i2c.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* + * I2C bus configuration for AirBrainH743 + * + * I2C1: Internal bus - PB6 (SCL), PB7 (SDA) + * Devices: DPS310 baro @ 0x76, LIS2MDL compass @ 0x1E + */ + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), +}; diff --git a/boards/gearup/airbrainh743/src/init.c b/boards/gearup/airbrainh743/src/init.c new file mode 100644 index 0000000000..0f2a75d6d2 --- /dev/null +++ b/boards/gearup/airbrainh743/src/init.c @@ -0,0 +1,228 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * AirBrainH743-specific early startup code. + */ + +#include "board_config.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(FLASH_BASED_PARAMS) +#include +#endif + +#ifdef CONFIG_MTD_W25N +extern FAR struct mtd_dev_s *w25n_initialize(FAR struct spi_dev_s *dev, uint32_t spi_devid); +#endif + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + UNUSED(ms); +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_as_pwm_input(i))); + } + + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. + * + ************************************************************************************/ +__EXPORT void stm32_boardinitialize(void) +{ + /* Reset PWM first thing */ + board_on_reset(-1); + + /* configure LEDs */ + board_autoled_initialize(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. + * + ****************************************************************************/ +__EXPORT int board_app_initialize(uintptr_t arg) +{ + /* Need hrt running before using the ADC */ + px4_platform_init(); + + /* configure SPI interfaces */ + stm32_spiinitialize(); + + /* configure the DMA allocator */ + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_off(LED_GREEN); + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_RED); + } + +#ifdef CONFIG_MTD_W25N + /* Initialize W25N01GV NAND Flash on SPI2 */ + struct spi_dev_s *spi2 = stm32_spibus_initialize(2); + + if (!spi2) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI2 for W25N\n"); + led_on(LED_RED); + + } else { + struct mtd_dev_s *mtd = w25n_initialize(spi2, 0); + + if (!mtd) { + syslog(LOG_ERR, "[boot] FAILED to initialize W25N MTD driver\n"); + led_on(LED_RED); + + } else { + int ret = register_mtddriver("/dev/mtd0", mtd, 0755, NULL); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to register MTD driver: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); + +#ifdef CONFIG_FS_LITTLEFS + ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, "autoformat"); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to mount littlefs: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] LittleFS mounted at /fs/microsd\n"); + } + +#endif + } + } + } + +#endif + +#if defined(FLASH_BASED_PARAMS) + /* Initialize parameters in internal flash (sector 15, 128KB at 0x081E0000) */ + static sector_descriptor_t params_sector_map[] = { + {15, 128 * 1024, 0x081E0000}, + {0, 0, 0}, + }; + + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + led_on(LED_RED); + } + +#endif + + /* Configure the HW based on the manifest */ + px4_platform_configure(); + + return OK; +} diff --git a/boards/gearup/airbrainh743/src/led.c b/boards/gearup/airbrainh743/src/led.c new file mode 100644 index 0000000000..016ef9f822 --- /dev/null +++ b/boards/gearup/airbrainh743/src/led.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +#ifdef CONFIG_ARCH_LEDS +static bool nuttx_owns_leds = true; +static const uint8_t xlatpx4[] = {1, 2, 4, 0}; +# define xlat(p) xlatpx4[(p)] +static uint32_t g_ledmap[] = { + GPIO_nLED_RED, // Indexed by BOARD_LED_RED + GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE +}; + +#else + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_nLED_RED, // LED_RED + GPIO_nLED_GREEN, // LED_GREEN + GPIO_nLED_BLUE, // LED_BLUE +}; + +#endif + +__EXPORT void led_init(void) +{ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + if (g_ledmap[l] != 0) { + stm32_configgpio(g_ledmap[l]); + } + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on (active low LEDs) */ + if (led < (int)(sizeof(g_ledmap) / sizeof(g_ledmap[0])) && g_ledmap[led] != 0) { + stm32_gpiowrite(g_ledmap[led], !state); + } +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + if (led < (int)(sizeof(g_ledmap) / sizeof(g_ledmap[0])) && g_ledmap[led] != 0) { + return !stm32_gpioread(g_ledmap[led]); + } + + return false; +} + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} + +#ifdef CONFIG_ARCH_LEDS +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + led_init(); +} + +void board_autoled_on(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_HEAPALLOCATE: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_IRQSENABLED: + phy_set_led(BOARD_LED_BLUE, false); + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_STACKCREATED: + phy_set_led(BOARD_LED_GREEN, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, true); + break; + + case LED_IDLE: + phy_set_led(BOARD_LED_RED, true); + break; + } +} + +void board_autoled_off(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, false); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, false); + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, false); + break; + + case LED_IDLE: + phy_set_led(BOARD_LED_RED, false); + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/gearup/airbrainh743/src/spi.cpp b/boards/gearup/airbrainh743/src/spi.cpp new file mode 100644 index 0000000000..05559c44d2 --- /dev/null +++ b/boards/gearup/airbrainh743/src/spi.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +/* + * SPI bus configuration for AirBrainH743 + * + * SPI1: IMU (Invensensev3/ICM42688P) - PA5 SCK, PA6 MISO, PA7 MOSI, PA3 CS + * SPI2: W25N Flash - PD3 SCK, PB14 MISO, PC3 MOSI, PD4 CS + * SPI4: External/AUX - PE12 SCK, PE5 MISO, PE6 MOSI + */ + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortA, GPIO::Pin3}), + }), + initSPIBus(SPI::Bus::SPI2, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortD, GPIO::Pin4}), // W25N Flash + }), + initSPIBusExternal(SPI::Bus::SPI4, { + initSPIConfigExternal(SPI::CS{GPIO::PortB, GPIO::Pin3}), // User 1 GPIO as chip select + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/gearup/airbrainh743/src/timer_config.cpp b/boards/gearup/airbrainh743/src/timer_config.cpp new file mode 100644 index 0000000000..e91005bb7a --- /dev/null +++ b/boards/gearup/airbrainh743/src/timer_config.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* + * PWM output configuration for AirBrainH743 + * + * M1: PE14 (TIM1_CH4) + * M2: PE13 (TIM1_CH3) + * M3: PE11 (TIM1_CH2) + * M4: PE9 (TIM1_CH1) + * M5: PB0 (TIM3_CH3) + * M6: PB1 (TIM3_CH4) + * M7: PB10 (TIM2_CH3) + * M8: PB11 (TIM2_CH4) + * M9: PA2 (TIM5_CH3) - LED strip + */ + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer1, DMA{DMA::Index1, DMA::Stream0, DMA::Channel6}), + initIOTimer(Timer::Timer3, DMA{DMA::Index1, DMA::Stream2, DMA::Channel5}), + initIOTimer(Timer::Timer2, DMA{DMA::Index1, DMA::Stream6, DMA::Channel3}), + initIOTimer(Timer::Timer5), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}), // M1 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}), // M2 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), // M3 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), // M4 + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}), // M5 + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortB, GPIO::Pin1}), // M6 + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel3}, {GPIO::PortB, GPIO::Pin10}), // M7 + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel4}, {GPIO::PortB, GPIO::Pin11}), // M8 + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel3}, {GPIO::PortA, GPIO::Pin2}), // M9 (LED) +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/gearup/airbrainh743/src/usb.c b/boards/gearup/airbrainh743/src/usb.c new file mode 100644 index 0000000000..a1c5d345dc --- /dev/null +++ b/boards/gearup/airbrainh743/src/usb.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file usb.c + * + * Board-specific USB functions. + */ + +#include "board_config.h" +#include +#include +#include +#include + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the board. + * + ************************************************************************************/ + +__EXPORT void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up */ + + /* Configure the OTG FS VBUS sensing GPIO */ +#ifdef CONFIG_STM32H7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); +#endif +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * + ************************************************************************************/ +__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} diff --git a/docs/en/SUMMARY.md b/docs/en/SUMMARY.md index cafc85b353..f141f91679 100644 --- a/docs/en/SUMMARY.md +++ b/docs/en/SUMMARY.md @@ -178,6 +178,7 @@ - [CubePilot Cube Orange (CubePilot)](flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow (CubePilot)](flight_controller/cubepilot_cube_yellow.md) - [Cube Wiring Quickstart](assembly/quick_start_cube.md) + - [Gear Up AirBrainH743](flight_controller/gearup_airbrainh743.md) - [Holybro Kakute H7v2](flight_controller/kakuteh7v2.md) - [Holybro Kakute H7mini](flight_controller/kakuteh7mini.md) - [Holybro Kakute H7](flight_controller/kakuteh7.md) diff --git a/docs/en/flight_controller/autopilot_manufacturer_supported.md b/docs/en/flight_controller/autopilot_manufacturer_supported.md index aa1d4cb5cb..9cdb3492e4 100644 --- a/docs/en/flight_controller/autopilot_manufacturer_supported.md +++ b/docs/en/flight_controller/autopilot_manufacturer_supported.md @@ -25,6 +25,7 @@ The boards in this category are: - [CubePilot Cube Orange+](../flight_controller/cubepilot_cube_orangeplus.md) - [CubePilot Cube Orange](../flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow](../flight_controller/cubepilot_cube_yellow.md) +- [Gear Up AirBrainH743](../flight_controller/gearup_airbrainh743.md) - [Holybro Kakute H7v2](../flight_controller/kakuteh7v2.md) - [Holybro Kakute H7mini](../flight_controller/kakuteh7mini.md) - [Holybro Kakute H7](../flight_controller/kakuteh7.md) diff --git a/docs/en/flight_controller/gearup_airbrainh743.md b/docs/en/flight_controller/gearup_airbrainh743.md new file mode 100644 index 0000000000..44c3c9ecc1 --- /dev/null +++ b/docs/en/flight_controller/gearup_airbrainh743.md @@ -0,0 +1,96 @@ +# Gear Up AirBrainH743 + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://takeyourgear.com/) for hardware support. +::: + +::: info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +For more information and pinout, check the [GitHub documentation](https://github.com/GearUp-Company/AirBrainH743). + +## Key Features + +- MCU: STM32H743 32-bit processor running at 480 MHz +- IMU: ICM42688P +- Barometer: DPS310 +- Magnetometer: LIS2MDL (internal) +- 128MB NAND Flash for logging (W25N) +- 7x UARTs +- I2C, SPI +- 9x PWM Outputs (8 Motor outputs, 1 LED strip) +- Battery input voltage: 3S-10S +- Battery voltage/current monitoring +- 5V@2A and 10V@2.5A BEC outputs +- USB Type-C (IP68) +- EMC and ESD protection + +## Connectors and Pins + +:::warning +The pin order is different from the Pixhawk standard (compatible to the Betaflight standard). +::: + +### UARTs + +Current UART configuration: + +| UART | Device | Function | +| ------ | ---------- | ---------------------------- | +| USART1 | /dev/ttyS0 | Console/Debug | +| USART2 | /dev/ttyS1 | RC Input | +| USART3 | /dev/ttyS2 | TEL4 (DJI/MSP) | +| UART4 | /dev/ttyS3 | TEL1 | +| UART5 | /dev/ttyS4 | TEL2 | +| UART7 | /dev/ttyS5 | TEL3 (ESC Telemetry) | +| UART8 | /dev/ttyS6 | GPS1 | + +### Motor/Servo Outputs + +| Connector | Pin | Function | +| ----------| ------------------ | +| ESC | M1 | Motor 1 | +| ESC | M2 | Motor 2 | +| ESC | M3 | Motor 3 | +| ESC | M4 | Motor 4 | +| PWM | M5 | Motor 5 | +| PWM | M6 | Motor 6 | +| PWM | M7 | Motor 7 | +| PWM | M8 | Motor 8 | +| AUX | M9 | LED/PWM/etc. | + + + +## PX4 Bootloader Update + +Before PX4 firmware can be installed, the _PX4 bootloader_ must be flashed. +Download the [gearup_airbrainh743_bootloader.bin](https://github.com/PX4/PX4-Autopilot/blob/main/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin) bootloader binary and read [this page](../advanced_config/bootloader_update_from_betaflight.md) for flashing instructions. + +## Building Firmware + +To [build PX4](../dev_setup/building_px4.md) for this target: + +``` +make gearup_airbrainh743_default +``` + +## Installing PX4 Firmware + +Firmware can be installed in any of the normal ways: + +- Build and upload the source: + + ``` + make gearup_airbrainh743_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + You can use either pre-built firmware or your own custom firmware. + +## Debug Port + +### System Console + +UART1 (ttyS0) is configured for use as the [System Console](../debug/system_console.md). From 7715a4ab4c685120785cc614e72aefe5e14e02c2 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Thu, 15 Jan 2026 10:51:51 +1300 Subject: [PATCH 63/71] AirBrainH743: configure for active buzzer We can't use passive buzzers because the timer to drive the PWM would conflict with the motor outputs M7 and M8. --- boards/gearup/airbrainh743/src/board_config.h | 11 +++++++++-- boards/gearup/airbrainh743/src/timer_config.cpp | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/boards/gearup/airbrainh743/src/board_config.h b/boards/gearup/airbrainh743/src/board_config.h index 1515f395ad..f6317c8c0f 100644 --- a/boards/gearup/airbrainh743/src/board_config.h +++ b/boards/gearup/airbrainh743/src/board_config.h @@ -112,9 +112,16 @@ #define BOARD_HAS_PWM DIRECT_PWM_OUTPUT_CHANNELS -/* Tone alarm output - PA15 */ +/* Tone alarm output (directly connected to transistor switch of external buzzer) + * + * GPIO mode only (active buzzer) - passive buzzer with different tones is not + * supported because PA15 can only use TIM2, which is also used for motor outputs + * M7 (PB10, TIM2_CH3) and M8 (PB11, TIM2_CH4). The PWM tone alarm driver changes + * the timer's prescaler and auto-reload registers (shared across all channels), + * which would affect M7/M8 PWM frequency during tone playback. + */ #define GPIO_TONE_ALARM_IDLE /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) -#define GPIO_TONE_ALARM_GPIO /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TONE_ALARM_GPIO /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN15) /* ICM42688P FSYNC - directly connected to IMU via GPIO (no timer). diff --git a/boards/gearup/airbrainh743/src/timer_config.cpp b/boards/gearup/airbrainh743/src/timer_config.cpp index e91005bb7a..2fcea89362 100644 --- a/boards/gearup/airbrainh743/src/timer_config.cpp +++ b/boards/gearup/airbrainh743/src/timer_config.cpp @@ -45,6 +45,10 @@ * M7: PB10 (TIM2_CH3) * M8: PB11 (TIM2_CH4) * M9: PA2 (TIM5_CH3) - LED strip + * + * Note: TIM2 is shared with buzzer pin PA15 (TIM2_CH1). The buzzer is disabled + * by default because the tone alarm driver would change the timer prescaler/ARR + * which affects M7/M8 PWM frequency. See board_config.h for details. */ constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { From 34845a62b092fada2e04ea91f6e4cd0a027d491b Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Mon, 19 Jan 2026 06:09:29 +1300 Subject: [PATCH 64/71] AirBrainH743: add external I2C This is for future/later board revisions. --- boards/gearup/airbrainh743/nuttx-config/include/board.h | 7 +++++++ boards/gearup/airbrainh743/nuttx-config/nsh/defconfig | 1 + boards/gearup/airbrainh743/src/i2c.cpp | 2 ++ 3 files changed, 10 insertions(+) diff --git a/boards/gearup/airbrainh743/nuttx-config/include/board.h b/boards/gearup/airbrainh743/nuttx-config/include/board.h index 9898c25305..56aafd3eaa 100644 --- a/boards/gearup/airbrainh743/nuttx-config/include/board.h +++ b/boards/gearup/airbrainh743/nuttx-config/include/board.h @@ -319,6 +319,7 @@ /* I2C * * I2C1: Internal (PB6 SCL, PB7 SDA) + * I2C4: External (PD12 SCL, PD13 SDA) */ #define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 /* PB6 */ @@ -327,6 +328,12 @@ #define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN6) #define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN7) +#define GPIO_I2C4_SCL GPIO_I2C4_SCL_1 /* PD12 */ +#define GPIO_I2C4_SDA GPIO_I2C4_SDA_1 /* PD13 */ + +#define GPIO_I2C4_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTD | GPIO_PIN12) +#define GPIO_I2C4_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTD | GPIO_PIN13) + /* USB * diff --git a/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig index 56f41becc6..a31ca060ed 100644 --- a/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig +++ b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig @@ -190,6 +190,7 @@ CONFIG_STM32H7_DMACAPABLE=y CONFIG_STM32H7_DMAMUX1=y CONFIG_STM32H7_FLOWCONTROL_BROKEN=y CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C4=y CONFIG_STM32H7_I2C_DYNTIMEO=y CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 CONFIG_STM32H7_OTGFS=y diff --git a/boards/gearup/airbrainh743/src/i2c.cpp b/boards/gearup/airbrainh743/src/i2c.cpp index 9bb4992776..26e33dc7fe 100644 --- a/boards/gearup/airbrainh743/src/i2c.cpp +++ b/boards/gearup/airbrainh743/src/i2c.cpp @@ -38,8 +38,10 @@ * * I2C1: Internal bus - PB6 (SCL), PB7 (SDA) * Devices: DPS310 baro @ 0x76, LIS2MDL compass @ 0x1E + * I2C4: External bus - PD12 (SCL), PD13 (SDA) */ constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { initI2CBusInternal(1), + initI2CBusExternal(4), }; From 7d2d85e6ac187fa0be91e6bad369d5328b5812eb Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Tue, 3 Feb 2026 10:23:07 +1300 Subject: [PATCH 65/71] AirBrainH743: reformat littlefs if required --- boards/gearup/airbrainh743/src/init.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/boards/gearup/airbrainh743/src/init.c b/boards/gearup/airbrainh743/src/init.c index 0f2a75d6d2..2577ce282e 100644 --- a/boards/gearup/airbrainh743/src/init.c +++ b/boards/gearup/airbrainh743/src/init.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include @@ -188,7 +190,26 @@ __EXPORT int board_app_initialize(uintptr_t arg) syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); #ifdef CONFIG_FS_LITTLEFS - ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, "autoformat"); + ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, NULL); + + if (ret == 0) { + /* Verify the filesystem is usable by creating a test file */ + int fd = open("/fs/microsd/.mount_test", O_CREAT | O_WRONLY | O_TRUNC); + + if (fd >= 0) { + close(fd); + unlink("/fs/microsd/.mount_test"); + + } else { + syslog(LOG_WARNING, "[boot] littlefs mounted but not usable, reformatting\n"); + nx_umount2("/fs/microsd", 0); + ret = -1; + } + } + + if (ret < 0) { + ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, "forceformat"); + } if (ret < 0) { syslog(LOG_ERR, "[boot] FAILED to mount littlefs: %d\n", ret); From a98d68f919e1eeb5812b6ee49153d7f72db5f246 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Tue, 3 Feb 2026 10:41:15 +1300 Subject: [PATCH 66/71] AirBrainH743: use /fs/flash instead of /fs/microsd --- boards/gearup/airbrainh743/default.px4board | 1 + boards/gearup/airbrainh743/src/init.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/boards/gearup/airbrainh743/default.px4board b/boards/gearup/airbrainh743/default.px4board index bcb4b2b786..1af794b76c 100644 --- a/boards/gearup/airbrainh743/default.px4board +++ b/boards/gearup/airbrainh743/default.px4board @@ -1,5 +1,6 @@ CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROOT_PATH="/fs/flash" CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS6" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS3" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" diff --git a/boards/gearup/airbrainh743/src/init.c b/boards/gearup/airbrainh743/src/init.c index 2577ce282e..b2d2c23b52 100644 --- a/boards/gearup/airbrainh743/src/init.c +++ b/boards/gearup/airbrainh743/src/init.c @@ -190,25 +190,25 @@ __EXPORT int board_app_initialize(uintptr_t arg) syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); #ifdef CONFIG_FS_LITTLEFS - ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, NULL); + ret = nx_mount("/dev/mtd0", CONFIG_BOARD_ROOT_PATH, "littlefs", 0, NULL); if (ret == 0) { /* Verify the filesystem is usable by creating a test file */ - int fd = open("/fs/microsd/.mount_test", O_CREAT | O_WRONLY | O_TRUNC); + int fd = open(CONFIG_BOARD_ROOT_PATH "/.mount_test", O_CREAT | O_WRONLY | O_TRUNC); if (fd >= 0) { close(fd); - unlink("/fs/microsd/.mount_test"); + unlink(CONFIG_BOARD_ROOT_PATH "/.mount_test"); } else { syslog(LOG_WARNING, "[boot] littlefs mounted but not usable, reformatting\n"); - nx_umount2("/fs/microsd", 0); + nx_umount2(CONFIG_BOARD_ROOT_PATH, 0); ret = -1; } } if (ret < 0) { - ret = nx_mount("/dev/mtd0", "/fs/microsd", "littlefs", 0, "forceformat"); + ret = nx_mount("/dev/mtd0", CONFIG_BOARD_ROOT_PATH, "littlefs", 0, "forceformat"); } if (ret < 0) { @@ -216,7 +216,7 @@ __EXPORT int board_app_initialize(uintptr_t arg) led_on(LED_RED); } else { - syslog(LOG_INFO, "[boot] LittleFS mounted at /fs/microsd\n"); + syslog(LOG_INFO, "[boot] LittleFS mounted at %s\n", CONFIG_BOARD_ROOT_PATH); } #endif From fd9abf76fd1fcb2824b5434ffc0251629b788007 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Fri, 6 Feb 2026 08:13:08 +1300 Subject: [PATCH 67/71] Fixup docs --- docs/en/flight_controller/gearup_airbrainh743.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/flight_controller/gearup_airbrainh743.md b/docs/en/flight_controller/gearup_airbrainh743.md index 44c3c9ecc1..8fe379f606 100644 --- a/docs/en/flight_controller/gearup_airbrainh743.md +++ b/docs/en/flight_controller/gearup_airbrainh743.md @@ -9,6 +9,8 @@ Contact the [manufacturer](https://takeyourgear.com/) for hardware support. This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). ::: +Purchase from [takeyourgear.com](https://takeyourgear.com/pages/products/airbrain). + For more information and pinout, check the [GitHub documentation](https://github.com/GearUp-Company/AirBrainH743). ## Key Features @@ -89,8 +91,6 @@ Firmware can be installed in any of the normal ways: - [Load the firmware](../config/firmware.md) using _QGroundControl_. You can use either pre-built firmware or your own custom firmware. -## Debug Port - ### System Console UART1 (ttyS0) is configured for use as the [System Console](../debug/system_console.md). From ee196fadb84c7b740fe8726470a7cff083ab0d3b Mon Sep 17 00:00:00 2001 From: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> Date: Tue, 10 Feb 2026 14:49:40 +0900 Subject: [PATCH 68/71] gps: ubx: add output rate parameter (#26388) * gps: ubx: add parameter to configure module measurement rate (GPS_UBX_RATE) * gps: update submodule * submodule --- src/drivers/gps/gps.cpp | 8 ++++++++ src/drivers/gps/params.c | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/drivers/gps/gps.cpp b/src/drivers/gps/gps.cpp index f6cc8f8e75..b33e27ac22 100644 --- a/src/drivers/gps/gps.cpp +++ b/src/drivers/gps/gps.cpp @@ -786,6 +786,13 @@ GPS::run() param_get(handle, &gps_ubx_min_elev); } + int32_t gps_ubx_rate = 0; + handle = param_find("GPS_UBX_RATE"); + + if (handle != PARAM_INVALID) { + param_get(handle, &gps_ubx_rate); + } + handle = param_find("GPS_UBX_MODE"); GPSDriverUBX::UBXMode ubx_mode{GPSDriverUBX::UBXMode::Normal}; @@ -945,6 +952,7 @@ GPS::run() .dgnss_timeout = (uint8_t)gps_ubx_dgnss_to, .min_cno = (uint8_t)gps_ubx_min_cno, .min_elev = (int8_t)gps_ubx_min_elev, + .output_rate = (uint8_t)gps_ubx_rate, .heading_offset = heading_offset, .uart2_baudrate = f9p_uart2_baudrate, .ppk_output = ppk_output > 0, diff --git a/src/drivers/gps/params.c b/src/drivers/gps/params.c index dd37f58486..4eb8142128 100644 --- a/src/drivers/gps/params.c +++ b/src/drivers/gps/params.c @@ -114,6 +114,25 @@ PARAM_DEFINE_INT32(GPS_UBX_MIN_CNO, 0); */ PARAM_DEFINE_INT32(GPS_UBX_MIN_ELEV, 0); +/** + * u-blox GPS output rate + * + * Configure the output rate of u-blox GPS receivers (protocol v27+). + * When set to 0, automatic rate selection is used based on the receiver model. + * Default rates: M9N=8Hz, F9P L1L2=5Hz, F9P L1L5=5Hz, Others=10Hz. + * + * Note: Higher rates reduce satellite count (e.g., >8Hz limits to 16 SVs on M9N). + * Max rates vary by model and RTK mode: F9P L1L2=5-7Hz, F9P L1L5=7-8Hz, X20=25Hz. + * High rates at 115200 baud may cause dropouts. + * + * @min 0 + * @max 25 + * @unit Hz + * @reboot_required true + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_RATE, 0); + /** * Enable sat info (if available) * From 3fb1459c3302469b5539c97e390ea5be06482788 Mon Sep 17 00:00:00 2001 From: Jacob Dahl <37091262+dakejahl@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:36:35 +0900 Subject: [PATCH 69/71] ManualControl: fix payload power switch state when mapped with RC (RC_MAP_PAY_SW) (#26357) * ManualControl: Payload Power Switch: default PAYLOAD_POWER_EN false if RC_MAP_PAY_SW is configured. Apply initial switch state for Payload Power * make format * ManualControl: init power_en in init() * ManualControl: Apply payload power state on first switch receipt if not armed * simplfy * fix idefs * simplify --- src/modules/manual_control/ManualControl.cpp | 21 ++++++++++++++++++++ src/modules/manual_control/ManualControl.hpp | 1 + 2 files changed, 22 insertions(+) diff --git a/src/modules/manual_control/ManualControl.cpp b/src/modules/manual_control/ManualControl.cpp index 263cbaa027..759088524a 100644 --- a/src/modules/manual_control/ManualControl.cpp +++ b/src/modules/manual_control/ManualControl.cpp @@ -52,6 +52,15 @@ ManualControl::~ManualControl() bool ManualControl::init() { +#if defined(PAYLOAD_POWER_EN) + + // If the payload power switch is mapped, default to power off until the RC switch explicitly commands it on. + if (_param_rc_map_pay_sw.get()) { + PAYLOAD_POWER_EN(false); + } + +#endif // PAYLOAD_POWER_EN + ScheduleNow(); return true; } @@ -293,6 +302,18 @@ void ManualControl::processSwitches(hrt_abstime &now) } else if (!_armed) { // Directly initialize mode using RC switch but only before arming evaluateModeSlot(switches.mode_slot); +#if defined(PAYLOAD_POWER_EN) + + // Apply payload power state on first switch receipt if not armed + if (switches.payload_power_switch == manual_control_switches_s::SWITCH_POS_ON) { + PAYLOAD_POWER_EN(true); + + } else if (switches.payload_power_switch == manual_control_switches_s::SWITCH_POS_OFF + || switches.payload_power_switch == manual_control_switches_s::SWITCH_POS_MIDDLE) { + PAYLOAD_POWER_EN(false); + } + +#endif // PAYLOAD_POWER_EN } _previous_switches = switches; diff --git a/src/modules/manual_control/ManualControl.hpp b/src/modules/manual_control/ManualControl.hpp index 42856bb650..fd01cbdab0 100644 --- a/src/modules/manual_control/ManualControl.hpp +++ b/src/modules/manual_control/ManualControl.hpp @@ -149,6 +149,7 @@ private: (ParamBool) _param_man_arm_gesture, (ParamFloat) _param_man_kill_gest_t, (ParamBool) _param_com_arm_swisbtn, + (ParamInt) _param_rc_map_pay_sw, (ParamInt) _param_fltmode_1, (ParamInt) _param_fltmode_2, (ParamInt) _param_fltmode_3, From ecf8191aad5343d98e4f6d57124734b051affbb2 Mon Sep 17 00:00:00 2001 From: Balduin Date: Mon, 9 Feb 2026 11:59:36 +0100 Subject: [PATCH 70/71] Battery: Declare fault on overtemperature If the measured temperature exceeds the fixed threshold of 100 degC, a fault is declared, causing batteryCheck to show a failsafe warning to the user. --- src/lib/battery/battery.cpp | 4 ++++ src/lib/battery/battery.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/lib/battery/battery.cpp b/src/lib/battery/battery.cpp index 844f24de74..16b79a6bbd 100644 --- a/src/lib/battery/battery.cpp +++ b/src/lib/battery/battery.cpp @@ -330,6 +330,10 @@ uint16_t Battery::determineFaults() faults |= (1 << battery_status_s::FAULT_SPIKES); } + if (PX4_ISFINITE(_temperature_c) && _temperature_c > BAT_TEMP_MAX) { + faults |= (1 << battery_status_s::FAULT_OVER_TEMPERATURE); + } + return faults; } diff --git a/src/lib/battery/battery.h b/src/lib/battery/battery.h index 66dd73bf27..b432c80e27 100644 --- a/src/lib/battery/battery.h +++ b/src/lib/battery/battery.h @@ -217,4 +217,10 @@ private: static constexpr float OCV_DEFAULT = 4.2f; // [V] Initial per cell estimate of the open circuit voltage static constexpr float R_COVARIANCE = 0.1f; // Initial per cell covariance of the internal resistance static constexpr float OCV_COVARIANCE = 1.5f; // Initial per cell covariance of the open circuit voltage + + // Temperature [degC] above which an overtemperature fault is declared, + // leading to a failsafe warning recommending immediate landing. Note + // that depending on the setup this may be measured in/close to the + // battery (smart battery) or from a separate power monitor module. + static constexpr float BAT_TEMP_MAX = 100.0f; }; From 77d8e4f2139fc7347e7c049d84ae772fd76d62ee Mon Sep 17 00:00:00 2001 From: Eric Katzfey Date: Tue, 10 Feb 2026 09:31:27 -0700 Subject: [PATCH 71/71] VOXLPM: Updated driver to publish battery status at 20ms intervals. Changed printf to PX4_INFO. --- src/drivers/power_monitor/voxlpm/voxlpm.cpp | 22 ++++++++++----------- src/drivers/power_monitor/voxlpm/voxlpm.hpp | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/drivers/power_monitor/voxlpm/voxlpm.cpp b/src/drivers/power_monitor/voxlpm/voxlpm.cpp index 51a496bd6d..d25eec8374 100644 --- a/src/drivers/power_monitor/voxlpm/voxlpm.cpp +++ b/src/drivers/power_monitor/voxlpm/voxlpm.cpp @@ -254,11 +254,11 @@ VOXLPM::print_status() switch (_pm_type) { case VOXLPM_TYPE_V2_LTC: - printf("- V2 (LTC2964)\n"); + PX4_INFO("- V2 (LTC2964)"); break; case VOXLPM_TYPE_V3_INA: - printf("- V3 (INA231)\n"); + PX4_INFO("- V3 (INA231)"); break; default: @@ -267,27 +267,27 @@ VOXLPM::print_status() switch (_ch_type) { case VOXLPM_CH_TYPE_VBATT: - printf("- type: BATT\n"); + PX4_INFO("- type: BATT"); break; case VOXLPM_CH_TYPE_P5VDC: - printf("- type: P5VDC\n"); + PX4_INFO("- type: P5VDC"); break; case VOXLPM_CH_TYPE_P12VDC: - printf("- type: P12VDC\n"); + PX4_INFO("- type: P12VDC"); break; default: - printf("- type: UNKOWN\n"); + PX4_INFO("- type: UNKOWN"); break; } - printf(" - voltage: %9.4f VDC \n", (double)_voltage); - printf(" - current: %9.4f ADC \n", (double)_amperage); - printf(" - shunt: %9.4f mV, %9.4f mA\n", (double)_vshunt * 1000, (double)_vshuntamps * 1000); - printf(" - rsense: %9.6f ohm, cal: %i\n", (double)_rshunt, _cal); - printf(" - meas interval: %u us \n", _meas_interval_us); + PX4_INFO(" - voltage: %9.4f VDC ", (double)_voltage); + PX4_INFO(" - current: %9.4f ADC ", (double)_amperage); + PX4_INFO(" - shunt: %9.4f mV, %9.4f mA", (double)_vshunt * 1000, (double)_vshuntamps * 1000); + PX4_INFO(" - rsense: %9.6f ohm, cal: %i", (double)_rshunt, _cal); + PX4_INFO(" - meas interval: %u us ", _meas_interval_us); } void diff --git a/src/drivers/power_monitor/voxlpm/voxlpm.hpp b/src/drivers/power_monitor/voxlpm/voxlpm.hpp index e03326d622..4152bd0e54 100644 --- a/src/drivers/power_monitor/voxlpm/voxlpm.hpp +++ b/src/drivers/power_monitor/voxlpm/voxlpm.hpp @@ -246,7 +246,7 @@ private: int measure_ina231(); bool _initialized; - static constexpr unsigned _meas_interval_us{100_ms}; + static constexpr unsigned _meas_interval_us{20_ms}; perf_counter_t _sample_perf; perf_counter_t _comms_errors;