mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-31 02:16:53 +08:00
Docs beginner tutorials update (#26639)
* docs: module_template.md accuracy fix * Modernise and Fix up Hello sky example * Corrections * Apply suggestions from code review * Apply suggestions from code review * Fix up indentation
This commit is contained in:
@@ -12,13 +12,15 @@ These are covered in [Application/Module Template](../modules/module_template.md
|
|||||||
|
|
||||||
You will require the following:
|
You will require the following:
|
||||||
|
|
||||||
- [PX4 SITL Simulator](../simulation/index.md) _or_ a [PX4-compatible flight controller](../flight_controller/index.md).
|
- [Gazebo Simulator](../sim_gazebo_gz/index.md) (or another [PX4 SITL Simulator](../simulation/index.md)) _or_ a [PX4-compatible flight controller](../flight_controller/index.md).
|
||||||
- [PX4 Development Toolchain](../dev_setup/dev_env.md) for the desired target.
|
- [PX4 Development Toolchain](../dev_setup/dev_env.md) for the desired target.
|
||||||
- [Download the PX4 Source Code](../dev_setup/building_px4.md#download-the-px4-source-code) from Github
|
- [Download the PX4 Source Code](../dev_setup/building_px4.md#download-the-px4-source-code) from Github
|
||||||
|
|
||||||
The source code [PX4-Autopilot/src/examples/px4_simple_app](https://github.com/PX4/PX4-Autopilot/tree/main/src/examples/px4_simple_app) directory contains a completed version of this tutorial that you can review if you get stuck.
|
The source code [PX4-Autopilot/src/examples/px4_simple_app](https://github.com/PX4/PX4-Autopilot/tree/main/src/examples/px4_simple_app) directory contains a completed version of this tutorial that you can review if you get stuck.
|
||||||
|
|
||||||
- Rename (or delete) the **px4_simple_app** directory.
|
::: tip
|
||||||
|
Rename (or delete) the **px4_simple_app** directory.
|
||||||
|
:::
|
||||||
|
|
||||||
## Minimal Application
|
## Minimal Application
|
||||||
|
|
||||||
@@ -26,14 +28,14 @@ In this section we create a _minimal application_ that just prints out `Hello Sk
|
|||||||
This consists of a single _C_ file and a _cmake_ definition (which tells the toolchain how to build the application).
|
This consists of a single _C_ file and a _cmake_ definition (which tells the toolchain how to build the application).
|
||||||
|
|
||||||
1. Create a new directory **PX4-Autopilot/src/examples/px4_simple_app**.
|
1. Create a new directory **PX4-Autopilot/src/examples/px4_simple_app**.
|
||||||
1. Create a new C file in that directory named **px4_simple_app.c**:
|
2. Create a new C file in that directory named **px4_simple_app.c**:
|
||||||
- Copy in the default header to the top of the page.
|
- Copy in the default header to the top of the page.
|
||||||
This should be present in all contributed files!
|
This should be present in all contributed files!
|
||||||
|
|
||||||
```c
|
```c
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 PX4 Development Team. All rights reserved.
|
* Copyright (c) 2012-2026 PX4 Development Team. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -66,7 +68,7 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too
|
|||||||
```
|
```
|
||||||
|
|
||||||
- Copy the following code below the default header.
|
- Copy the following code below the default header.
|
||||||
This should be present in all contributed files!
|
Similar code should be present in all contributed files!
|
||||||
|
|
||||||
```c
|
```c
|
||||||
/**
|
/**
|
||||||
@@ -101,7 +103,7 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
1. Create and open a new _cmake_ definition file named **CMakeLists.txt**.
|
3. Create and open a new _cmake_ definition file named **CMakeLists.txt**.
|
||||||
Copy in the text below:
|
Copy in the text below:
|
||||||
|
|
||||||
```cmake
|
```cmake
|
||||||
@@ -147,6 +149,9 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that in your own modules you'd use the current copyright year!
|
||||||
|
We're using `2015` here to match the example.
|
||||||
|
|
||||||
The `px4_add_module()` method builds a static library from a module description.
|
The `px4_add_module()` method builds a static library from a module description.
|
||||||
- The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`).
|
- The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`).
|
||||||
- The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console.
|
- The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console.
|
||||||
@@ -161,10 +166,10 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too
|
|||||||
You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod`
|
You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod`
|
||||||
:::
|
:::
|
||||||
|
|
||||||
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)).
|
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)).
|
||||||
Copy in the text below:
|
Copy in the text below:
|
||||||
|
|
||||||
```text
|
```txt
|
||||||
menuconfig EXAMPLES_PX4_SIMPLE_APP
|
menuconfig EXAMPLES_PX4_SIMPLE_APP
|
||||||
bool "px4_simple_app"
|
bool "px4_simple_app"
|
||||||
default n
|
default n
|
||||||
@@ -179,27 +184,34 @@ In order to run it you first need to make sure that it is built as part of PX4.
|
|||||||
Applications are added to the build/firmware in the appropriate board-level _px4board_ file for your target:
|
Applications are added to the build/firmware in the appropriate board-level _px4board_ file for your target:
|
||||||
|
|
||||||
- PX4 SITL (Simulator): [PX4-Autopilot/boards/px4/sitl/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/sitl/default.px4board)
|
- PX4 SITL (Simulator): [PX4-Autopilot/boards/px4/sitl/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/sitl/default.px4board)
|
||||||
- Pixhawk v1/2: [PX4-Autopilot/boards/px4/fmu-v2/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v2/default.px4board)
|
- Pixhawk 6X (px4/fmu-v6x): [PX4-Autopilot/boards/px4/fmu-v6x/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6x/default.px4board)
|
||||||
- Pixracer (px4/fmu-v4): [PX4-Autopilot/boards/px4/fmu-v4/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v4/default.px4board)
|
|
||||||
- _px4board_ files for other boards can be found in [PX4-Autopilot/boards/](https://github.com/PX4/PX4-Autopilot/tree/main/boards)
|
- _px4board_ files for other boards can be found in [PX4-Autopilot/boards/](https://github.com/PX4/PX4-Autopilot/tree/main/boards)
|
||||||
|
|
||||||
To enable the compilation of the application into the firmware add the corresponding Kconfig key `CONFIG_EXAMPLES_PX4_SIMPLE_APP=y` in the _px4board_ file or run [boardconfig](../hardware/porting_guide_config.md#px4-menuconfig-setup) `make px4_fmu-v4_default boardconfig`:
|
To enable the compilation of the application into the firmware add the corresponding Kconfig key `CONFIG_EXAMPLES_PX4_SIMPLE_APP=y` in the _px4board_ file or run [boardconfig](../hardware/porting_guide_config.md#px4-menuconfig-setup).
|
||||||
|
|
||||||
|
For example, to edit the board config for FMUv6x you would do:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make fmu-v6x_default boardconfig
|
||||||
```
|
```
|
||||||
|
|
||||||
|
And then enable the app in the _boardconfig_ UI as shown:
|
||||||
|
|
||||||
|
```txt
|
||||||
examples --->
|
examples --->
|
||||||
[x] PX4 Simple app ----
|
[x] PX4 Simple app ----
|
||||||
```
|
```
|
||||||
|
|
||||||
::: info
|
::: info
|
||||||
The line will already be present for most files, because the examples are included in firmware by default.
|
Examples are opt-in and not included in firmware by default (although they are in SITL).
|
||||||
|
You must explicitly enable them as shown above.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Build the example using the board-specific command:
|
Build the example using the board-specific command:
|
||||||
|
|
||||||
- jMAVSim Simulator: `make px4_sitl_default jmavsim`
|
- Gazebo Simulator: `make px4_sitl gz_x500`
|
||||||
- Pixhawk v1/2: `make px4_fmu-v2_default` (or just `make px4_fmu-v2`)
|
- Pixhawk 6X: `make px4_fmu-v6x_default`
|
||||||
- Pixhawk v3: `make px4_fmu-v4_default`
|
- Other boards: [Building the Code](../dev_setup/building_px4.md)
|
||||||
- Other boards: [Building the Code](../dev_setup/building_px4.md#building-for-nuttx)
|
|
||||||
|
|
||||||
## Test App (Hardware)
|
## Test App (Hardware)
|
||||||
|
|
||||||
@@ -207,8 +219,7 @@ Build the example using the board-specific command:
|
|||||||
|
|
||||||
Enable the uploader and then reset the board:
|
Enable the uploader and then reset the board:
|
||||||
|
|
||||||
- Pixhawk v1/2: `make px4_fmu-v2_default upload`
|
- Pixhawk 6X: `make px4_fmu-v6x_default upload`
|
||||||
- Pixhawk v3: `make px4_fmu-v4_default upload`
|
|
||||||
|
|
||||||
It should print before you reset the board a number of compile messages and at the end:
|
It should print before you reset the board a number of compile messages and at the end:
|
||||||
|
|
||||||
@@ -293,14 +304,14 @@ The benefits of the PX4 hardware abstraction comes into play here!
|
|||||||
There is no need to interact in any way with sensor drivers and no need to update your app if the board or sensors are updated.
|
There is no need to interact in any way with sensor drivers and no need to update your app if the board or sensors are updated.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Individual message channels between applications are called [topics](../middleware/uorb.md). For this tutorial, we are interested in the [SensorCombined](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorCombined.msg) topic, which holds the synchronized sensor data of the complete system.
|
Individual message channels between applications are called [topics](../middleware/uorb.md). For this tutorial, we are interested in the [VehicleAcceleration](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAcceleration.msg) topic, which holds the filtered vehicle acceleration data.
|
||||||
|
|
||||||
Subscribing to a topic is straightforward:
|
Subscribing to a topic is straightforward:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <uORB/topics/sensor_combined.h>
|
#include <uORB/topics/vehicle_acceleration.h>
|
||||||
..
|
..
|
||||||
int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));
|
int sensor_sub_fd = orb_subscribe(ORB_ID(vehicle_acceleration));
|
||||||
```
|
```
|
||||||
|
|
||||||
The `sensor_sub_fd` is a topic handle and can be used to very efficiently perform a blocking wait for new data.
|
The `sensor_sub_fd` is a topic handle and can be used to very efficiently perform a blocking wait for new data.
|
||||||
@@ -311,9 +322,9 @@ Adding `poll()` to the subscription looks like (_pseudocode, look for the full i
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <uORB/topics/sensor_combined.h>
|
#include <uORB/topics/vehicle_acceleration.h>
|
||||||
..
|
..
|
||||||
int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));
|
int sensor_sub_fd = orb_subscribe(ORB_ID(vehicle_acceleration));
|
||||||
|
|
||||||
/* one could wait for multiple topics with this technique, just using one here */
|
/* one could wait for multiple topics with this technique, just using one here */
|
||||||
px4_pollfd_struct_t fds[] = {
|
px4_pollfd_struct_t fds[] = {
|
||||||
@@ -326,13 +337,13 @@ while (true) {
|
|||||||
..
|
..
|
||||||
if (fds[0].revents & POLLIN) {
|
if (fds[0].revents & POLLIN) {
|
||||||
/* obtained data for the first file descriptor */
|
/* obtained data for the first file descriptor */
|
||||||
struct sensor_combined_s raw;
|
struct vehicle_acceleration_s accel;
|
||||||
/* copy sensors raw data into local buffer */
|
/* copy sensors raw data into local buffer */
|
||||||
orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
|
orb_copy(ORB_ID(vehicle_acceleration), sensor_sub_fd, &accel);
|
||||||
PX4_INFO("Accelerometer:\t%8.4f\t%8.4f\t%8.4f",
|
PX4_INFO("Accelerometer:\t%8.4f\t%8.4f\t%8.4f",
|
||||||
(double)raw.accelerometer_m_s2[0],
|
(double)accel.xyz[0],
|
||||||
(double)raw.accelerometer_m_s2[1],
|
(double)accel.xyz[1],
|
||||||
(double)raw.accelerometer_m_s2[2]);
|
(double)accel.xyz[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -340,7 +351,7 @@ while (true) {
|
|||||||
Compile the app again by entering:
|
Compile the app again by entering:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make
|
make px4_sitl_default
|
||||||
```
|
```
|
||||||
|
|
||||||
### Testing the uORB Subscription
|
### Testing the uORB Subscription
|
||||||
@@ -399,7 +410,7 @@ The [complete example code](https://github.com/PX4/PX4-Autopilot/blob/main/src/e
|
|||||||
```c
|
```c
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2019 PX4 Development Team. All rights reserved.
|
* Copyright (c) 2012-2026 PX4 Development Team. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -448,7 +459,7 @@ The [complete example code](https://github.com/PX4/PX4-Autopilot/blob/main/src/e
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <uORB/uORB.h>
|
#include <uORB/uORB.h>
|
||||||
#include <uORB/topics/sensor_combined.h>
|
#include <uORB/topics/vehicle_acceleration.h>
|
||||||
#include <uORB/topics/vehicle_attitude.h>
|
#include <uORB/topics/vehicle_attitude.h>
|
||||||
|
|
||||||
__EXPORT int px4_simple_app_main(int argc, char *argv[]);
|
__EXPORT int px4_simple_app_main(int argc, char *argv[]);
|
||||||
@@ -457,8 +468,8 @@ int px4_simple_app_main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
PX4_INFO("Hello Sky!");
|
PX4_INFO("Hello Sky!");
|
||||||
|
|
||||||
/* subscribe to sensor_combined topic */
|
/* subscribe to vehicle_acceleration topic */
|
||||||
int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));
|
int sensor_sub_fd = orb_subscribe(ORB_ID(vehicle_acceleration));
|
||||||
/* limit the update rate to 5 Hz */
|
/* limit the update rate to 5 Hz */
|
||||||
orb_set_interval(sensor_sub_fd, 200);
|
orb_set_interval(sensor_sub_fd, 200);
|
||||||
|
|
||||||
@@ -499,20 +510,20 @@ int px4_simple_app_main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (fds[0].revents & POLLIN) {
|
if (fds[0].revents & POLLIN) {
|
||||||
/* obtained data for the first file descriptor */
|
/* obtained data for the first file descriptor */
|
||||||
struct sensor_combined_s raw;
|
struct vehicle_acceleration_s accel;
|
||||||
/* copy sensors raw data into local buffer */
|
/* copy sensors raw data into local buffer */
|
||||||
orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
|
orb_copy(ORB_ID(vehicle_acceleration), sensor_sub_fd, &accel);
|
||||||
PX4_INFO("Accelerometer:\t%8.4f\t%8.4f\t%8.4f",
|
PX4_INFO("Accelerometer:\t%8.4f\t%8.4f\t%8.4f",
|
||||||
(double)raw.accelerometer_m_s2[0],
|
(double)accel.xyz[0],
|
||||||
(double)raw.accelerometer_m_s2[1],
|
(double)accel.xyz[1],
|
||||||
(double)raw.accelerometer_m_s2[2]);
|
(double)accel.xyz[2]);
|
||||||
|
|
||||||
/* set att and publish this information for other apps
|
/* set att and publish this information for other apps
|
||||||
the following does not have any meaning, it's just an example
|
the following does not have any meaning, it's just an example
|
||||||
*/
|
*/
|
||||||
att.q[0] = raw.accelerometer_m_s2[0];
|
att.q[0] = accel.xyz[0];
|
||||||
att.q[1] = raw.accelerometer_m_s2[1];
|
att.q[1] = accel.xyz[1];
|
||||||
att.q[2] = raw.accelerometer_m_s2[2];
|
att.q[2] = accel.xyz[2];
|
||||||
|
|
||||||
orb_publish(ORB_ID(vehicle_attitude), att_pub, &att);
|
orb_publish(ORB_ID(vehicle_attitude), att_pub, &att);
|
||||||
}
|
}
|
||||||
@@ -524,7 +535,6 @@ int px4_simple_app_main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
PX4_INFO("exiting");
|
PX4_INFO("exiting");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -22,13 +22,15 @@ The example shows how.
|
|||||||
In summary:
|
In summary:
|
||||||
|
|
||||||
1. Specify the dependency on the work queue library in the cmake definition file ([CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/CMakeLists.txt)):
|
1. Specify the dependency on the work queue library in the cmake definition file ([CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/CMakeLists.txt)):
|
||||||
```
|
|
||||||
|
```txt
|
||||||
...
|
...
|
||||||
DEPENDS
|
DEPENDS
|
||||||
px4_work_queue
|
px4_work_queue
|
||||||
```
|
```
|
||||||
1. In addition to `ModuleBase`, the task should also derive from `ScheduledWorkItem` (included from [ScheduledWorkItem.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp))
|
|
||||||
1. Specify the queue to add the task to in the constructor initialisation.
|
2. In addition to `ModuleBase`, the task should also derive from `ScheduledWorkItem` (included from [ScheduledWorkItem.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp))
|
||||||
|
3. Specify the queue to add the task to in the constructor initialisation.
|
||||||
The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below:
|
The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@@ -43,9 +45,11 @@ In summary:
|
|||||||
The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49).
|
The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49).
|
||||||
:::
|
:::
|
||||||
|
|
||||||
1. Implement the `ScheduledWorkItem::Run()` method to perform "work".
|
4. Implement the `ScheduledWorkItem::Run()` method to perform "work".
|
||||||
1. Implement the `task_spawn` method, specifying that the task is a work queue (using the `task_id_is_work_queue` id.
|
5. Implement the `task_spawn` method, specifying that the task is a work queue (using the `task_id_is_work_queue` id).
|
||||||
1. Schedule the work queue task using one of the scheduling methods (in the example we use `ScheduleOnInterval` from within the `init` method).
|
6. Schedule the work queue task using one of the scheduling methods.
|
||||||
|
In the example, `init()` calls `registerCallback()` on a uORB subscription so that `Run()` is triggered whenever a new `sensor_accel` message is published.
|
||||||
|
`ScheduleOnInterval` is an alternative for fixed-rate scheduling.
|
||||||
|
|
||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
@@ -61,6 +65,6 @@ The template demonstrates the following additional features/aspects that are req
|
|||||||
[startup script](../concept/system_startup.md).
|
[startup script](../concept/system_startup.md).
|
||||||
- Command-line argument parsing.
|
- Command-line argument parsing.
|
||||||
- Documentation: the `PRINT_MODULE_*` methods serve two purposes (the API is
|
- Documentation: the `PRINT_MODULE_*` methods serve two purposes (the API is
|
||||||
documented [in the source code](https://github.com/PX4/PX4-Autopilot/blob/v1.8.0/src/platforms/px4_module.h#L381)):
|
documented [in the source code](https://github.com/PX4/PX4-Autopilot/blob/v1.17/platforms/common/include/px4_platform_common/module.h)):
|
||||||
- They are used to print the command-line usage when entering `module help` on the console.
|
- They are used to print the command-line usage when entering `module help` on the console.
|
||||||
- They are automatically extracted via script to generate the [Modules & Commands Reference](../modules/modules_main.md) page.
|
- They are automatically extracted via script to generate the [Modules & Commands Reference](../modules/modules_main.md) page.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2019 PX4 Development Team. All rights reserved.
|
* Copyright (c) 2012-2026 PX4 Development Team. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|||||||
Reference in New Issue
Block a user