Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • danc/MicroCART
  • snawerdt/MicroCART_17-18
  • bbartels/MicroCART_17-18
  • jonahu/MicroCART
4 results
Show changes
Showing
with 2059 additions and 0 deletions
---
title: Out of tree build
page_id: oot
---
It is possible to have an out-of-tree build of parts of the crazyflie firmware. This enables developers to work on elements without worrrying about merging it with the full code base.
# App layer.
Technically the app layer is an example of an out of tree build. Follow the [app layer intructions](/docs/userguides/app_layer.md) for this.
# OOT extimators
In a seperate folder make a Makefile which contain the following content:
```
CFLAGS += -DOOT_ESTIMATOR
VPATH += src/
PROJ_OBJ += estimator_out_of_tree.o
CRAZYFLIE_BASE=[LOCATION OF THE CRAZYFLIE FIRMWARE]
include $(CRAZYFLIE_BASE)/Makefile
```
in [your_estimator_out_of_tree].c in the src folder you will just need to make sure that the following functions are filled:
* ```init = estimatorOutOfTreeInit```
* ```test = estimatorOutOfTreeTest```
* ```update = estimatorOutOfTree```
* ```name = "OOT```
# OOT Controllers
Not yet implemented. Please request this feature in the [crazyflie-firmware issue list](https://github.com/bitcraze/crazyflie-firmware/issues)
---
title: On-chip debugging
page_id: openocd_gdb_debugging
---
One of the key components of getting really serious about developing on
the crazyflie, is to dive into the C-based firmware. If you really want
to do some major changes to the intrinsic of the code, it is essential
to have proper tools to be able to debug the code (place breakpoints,
read real-time values ect\...). On this page, we will put a few examples
how to do this with IDE\'s and different environments.
> **_NOTE:_**
> This page requires our debug adapter and ST Link V2 Debugger! See
> this page: [Debug adapter](https://wiki.bitcraze.io/projects:crazyflie2:debugadapter:index)
## Debugging using VS Code
Thanks to the [Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) extension, it is now easily possible to debug ARM executables straight inside of VS Code!
### Mac OS and Ubuntu
#### Prerequisites
First ensure that you have the ARM GCC toolchain and OpenOCD installed and in your path. To check, run:
which openocd
which arm-none-eabi-gcc
The path to your OpenOCD binary and ARM GCC binary should output. If not, try installing them again.
##### Ubuntu
These steps have been tested on Ubuntu 20.04. The link to gdb-multiarch is required because Ubuntu does not ship arm-none-eabi-gdb anymore, but the new gdb-multiarch that supports all architecture.
sudo apt-get install openocd
sudo apt-get install gcc-arm-none-eabi gdb-multiarch
sudo ln -s /usr/bin/gdb-multiarch /usr/local/bin/arm-none-eabi-gdb
If you do not have vscode yet, the easiest way to install it on Ubuntu is via snap using 'Ubuntu Software' of by typing:
sudo snap install --classic code
##### Mac OS
brew install open-ocd
brew tap PX4/homebrew-px
brew install arm-none-eabi-gcc
### The Cortex Debug Extension
Install the [extension](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) either by clicking "Install" on the web page, or by searching "Cortex Debug" in the Extensions tab of VS Code.
Click on "Run", then "Add Configuration", then "Cortex Debug".
![VS Code add configuration](/docs/images/vscode_add_configuration.webp)
This should automatically create the needed "launch.json" file.
### Configuring Cortex Debug
Inside of the file, replace everything with the following:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "./cf2.elf",
"request": "launch",
"type": "cortex-debug",
"device": "STM32F405",
"svdFile": "STM32F405.svd",
"servertype": "openocd",
"configFiles": ["interface/stlink-v2.cfg", "target/stm32f4x.cfg"],
"runToMain": true,
"preLaunchCommands": [
"set mem inaccessible-by-default off",
"enable breakpoint",
"monitor reset"
]
}
]
}
### Explaining the Cortex Debug configuration
- "svdFile" refers to the necessary file for peripheral registers to show up nicely in the debug pane, all named and structured; we'll add it in the next step
- "configFiles" refers to the files you need so that OpenOCD knows what device and interface you're using; it should already come with them
- "runToMain" tells the GDB debug server to jump to main by default
- "preLaunchCommands" specifies the commands for the GDB server to send before giving away control to you; the commands here mimic the options that the above tutorial for Eclipse specifies
### Installing the SVD file
Now for the SVD file: just download it from [here](https://raw.githubusercontent.com/posborne/cmsis-svd/master/data/STMicro/STM32F405.svd) and into your root directory. Make sure it has the exact name of "STM32F405.svd"!
### Debugging!
After all this, go to the Debug tab of VS Code (on the left sidebar, the icon with the little bug next to the play button), and hit that play button next to "Run"!
If you followed everything, it should start running nicely and look a little something like this:
![VS Code Cortex Debug](/docs/images/vscode_cortex_debug.webp)
Notice the nice peripherals pane at the bottom, along with the variables pane at the top. Awesome, now you can code _and_ debug all within VS Code!
---
## Debugging using eclipse
### Ubuntu
> **_Versions:_**
>
> - Ubuntu 18.04.2 LTS (64 bit)
> - Eclipse 2019-03 (Eclipse IDE for C/C++ Developers)
#### Installing prerequisites
First install GDB and openOCD:
sudo apt-get update
sudo apt-get install gdb
sudo apt-get install openocd
Then install java:
sudo apt install default-jre
Then install eclipse itself: Go to their download page: [eclipse
20](https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/2019-03/R/eclipse-cpp-2019-03-R-linux-gtk-x86_64.tar.gz)
and then go into you download folder and unzip the file.
tar -zxvf "your-downloaded-file".tar.gz
and start up eclipse:
"YOUR-UNZIPPED-FOLDER"/.eclipse
#### Installing required Eclipse Plugins
Install the C++ development tools and GNU MCU plugin by following the
instructions [here](https://gnu-mcu-eclipse.github.io/plugins/install/).
- C++ Development - Follow the instructions under the header \'CDT\'.
- GNU MCU plugin - Follow the instructions under the header \'Plug-ins
install/update -\> The Eclipse Marketplace way\'
#### Import Crazyflie Firmware
First import the
[crazyflie-firmware](https://github.com/bitcraze/crazyflie-firmware)
into eclipse:
- File > import...
- C/C++ > Existing Code as Makefile Project -> Next
- Give it a name
- Existing Code Location > Browse... > //Look for the firmware folder//
- //Toolchain for Indexer Settings// can be ignored.
- Finish
#### Setting up Eclipse Debugging environment
- Go to: Run \> Debug Configurations\...
- Double click \'GDB OpenOCD Debugging\'
Now input the following settings in the debug configurations:
##### Main
![stm openocd main](/docs/images/stm_openocd_main.png)
Insert the filepath to the cf2.elf file to _C/C++ Application_.
##### Debugger
![stm openocd debug](/docs/images/stm_openocd_debugger.png)
check the following settings: OpenOCD setup -\> Config options: \<code\>
-f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c targets
\</code\> GDB Client Setup:
- Executable name: Filepath to gdb toolchain
- Commands: \<code\> set mem inaccessible-by-default off \</code\>
##### Startup
![stm openocd startup](/docs/images/stm_openocd_startup.png)
##### Hit Debug!
If you don\'t see any errors, eclipse should go to an dedicated
debugging environment automatically and it automatically halts the
crazyflie\'s firmware before it goes into the main function of
src/init/main.c. Press F8 or Run \> Resume to let it continue and place
a breakpoints anywhere in the code (double clicking just in front of the
line in the gray area or press Shift+Ctrl+B). Now you should be able to
read out the values of the defined variables at that very position.
---
Make sure that your cf2.elf is the
same as the one you uploaded to the crazyflie!
---
### Mac OS
Install gdb and openocd
brew install gdb
brew install open-ocd
Install java JDK [java
download](https://www.oracle.com/technetwork/java/javase/downloads/index.html)
Download eclipse [eclipse
download](https://www.eclipse.org/downloads/download.php?file=/oomph/epp/2019-06/R/eclipse-inst-mac64.dmg)
Choose destination folders - Install
Run eclipse and choose work folder
##### Installing required eclipse Plugins
The rest is the same as for Linux. Make sure that the arm-none-eabi-gcc
is properly installed and its path is configured in the _debug
configurations_.
---
title: Getting the serial number of the Crazyflie 2.X
page_id: serial
---
The Crazyflie 2.X ID is a character string of 24 characters. It is
unique to each Crazyflie 2.X.
Windows
-------
- Open the \"Device manager\" and find the Crazyflie 2.0/2.1.
- Right click on Crazyflie 2.0/2.1, go in \"Properties\" then in the
tab \"Details\".
- In the drop-box select \"Device instance path\".
The serial number is located just after \"5740\\\", in the following
screen it starts by 41:
![windows serial](/docs/images/windows_serial.png){:width=500x}
By right-clicking on the string you can copy it.
Linux
-----
Open a terminal and type (ie. cop-paste) the following command:
sudo lsusb -v -d 0483:5740 | grep iSerial
The Crazyflie serial is then displayed (here it starts by 41):
![linux serial](/docs/images/linux_serial.png)
Mac OS X
--------
From the \"About this mac\" menu, click on \"System reports\...\"
![mac serial](/docs/images/mac_serial_about.png){:width=400px}
Then click on \"USB\", locate the Crazyflie 2 and the serial number can
be copied from there
![mac serial 2](/docs/images/mac_serial.png){:width=500px}
---
title: Development for STM32
page_id: starting_development
---
This page aims at documenting how to start developing with Crazyflie.
This document should work for the Crazyflie 2.X.
### STM32
Clone the crazyflie-firmware project, or update it using the virtual
machine \"Update all projects\" script. For Crazyflie 2.X make sure the current branch is \"**master**.\"
~$ cd projects/crazyflie-firmware/
crazyflie-firmware$ git checkout master
And make sure the `submodules` are up-to-date.
```
crazyflie-firmware$ git submodule init
crazyflie-firmware$ git submodule update
```
Then make the firmware.
For **Crazyflie 2.X**:
```
crazyflie-firmware$ make PLATFORM=cf2
(...)
DFUse cf2.dfu
Build for the CF2 platform!
Build 00:00000000 (20XX.XX.X-XX) CLEAN
Version extracted from git
Crazyloader build!
Flash | 218132/1032192 (21%), 814060 free | text: 213024, data: 5108, ccmdata: 0
RAM | 71564/131072 (55%), 59508 free | bss: 66456, data: 5108
CCM | 43528/65536 (66%), 22008 free | ccmbss: 43528, ccmdata: 0
```
To program using the radio bootloader, first install the cflib and cfclient, and put the CF2.X in bootloader mode:
For **Crazyflie 2.X**:
```
crazyflie-firmware$ make cload
```
From command line the flash make target flashed the firmware using
programming cable
```
crazyflie-firmware$ make flash
```
---
title: Adding a new system task
page_id: systemtask
---
**First check out if you can use the [new app layer](/docs/userguides/app_layer.md), which might be enough for your purpose already**
This howto describes how to create a new system task.
A FreeRTOS task is similar to a thread on a standard operating system.
It has its own function call stack, and can be preempted by the RTOS scheduler.
Typical hazards and techniques of shared-memory multithreaded programming apply.
A new task is most often needed when adding a fundamentally new subsystem
to the Crazyflie firmware.
If the new subsystem needs to do
significant computation in response to inputs such as CRTP radio messages, it
should receive those inputs on a queue and perform the computation within
its own task instead of blocking the radio task.
In this example, we will set up the skeleton for such a new subsystem.
Development environment
-----------------------
You should have the
[crazyflie-firmware](https://github.com/bitcraze/crazyflie-firmware) and
[crazyflie-clients-python](https://github.com/bitcraze/crazyflie-clients-python)
cloned in the same folder. If you are using the [Bitcraze
VM](https://github.com/bitcraze/bitcraze-vm) this is already the case.
The Crazyflie firmware should be on Master branch.
For the rest of the howto you will work in the crazyflie-firmware
project.
Setting the task constants
--------------------------
Each task has a few constants that are stored globally in `src/config/config.h`.
First, set the task priority. The FreeRTOS scheduler always prefers to run
a higher-priority task. High priorities should be reserved for very
time-sensitive tasks like the main stabilizer loop.
In `config.h`, after the existing task priorities, add the line
``` {.c}
#define EXAMPLE_TASK_PRI 1
```
Next, each task has a name.
In `config.h`, after the existing task names, add the line
``` {.c}
#define EXAMPLE_TASK_NAME "EXAMPLE"
```
Finally, we must select a fixed size for the task's function call stack.
`configMINIMAL_STACK_SIZE` gives a fairly small stack.
Tasks that do lots of computation will almost certainly need larger stacks.
In `config.h`, after the existing task stack sizes, add the line
``` {.c}
#define EXAMPLE_TASK_STACKSIZE configMINIMAL_STACK_SIZE
```
Implementing the task
---------------------
High level tasks (those that do not directly talk to hardware) usually go in
the `modules` directory. We will walk through the sections needed in a
new file `src/modules/src/example.c`.
First, include the necessary system header files:
``` {.c}
#include "config.h"
#include "debug.h"
#include "FreeRTOS.h"
#include "queue.h"
#include "static_mem.h"
#include "task.h"
```
### File-static variables
Next, we statically allocate the queue to hold inputs from
other parts of the system such as the radio.
Here we just hold integers in the queue. Often it will be a struct instead.
A queue of length 1 is appropriate if new inputs supersede old ones.
For example, if the input controls the current LED color,
we do not care which other colors were requested in the past.
Note that the `STATIC_MEM_*_ALLOC` family of macros expand to static
variable declarations, and can be used outside of any function scope.
``` {.c}
static xQueueHandle inputQueue;
STATIC_MEM_QUEUE_ALLOC(inputQueue, 1, sizeof(int));
```
Next, we allocate the task call stack and other necessary memory for OS
bookkeeping.
The FreeRTOS task API requires that task functions take a `void *` argument.
``` {.c}
static void exampleTask(void*);
STATIC_MEM_TASK_ALLOC(exampleTask, EXAMPLE_TASK_STACKSIZE);
```
### Functions
Next, we implement the `Init()` function.
This should contain all of the FreeRTOS allocations and initializations
that need to last as long as the firmware is running.
Note the use of the constants we defined in `config.h`.
Later in this howto, we will need to edit another file to call the `Init()`.
``` {.c}
static bool isInit = false;
void exampleTaskInit() {
inputQueue = STATIC_MEM_QUEUE_CREATE(inputQueue);
// TODO
STATIC_MEM_TASK_CREATE(exampleTask, exampleTask, EXAMPLE_TASK_NAME, NULL, EXAMPLE_TASK_PRI);
isInit = true;
}
```
Next, we implement the `Test()` function.
Usually this does not do much, besides verify that `Init()` has been called.
Later in this howto, we will need to edit another file to call the `Test()`.
``` {.c}
bool exampleTaskTest() {
return isInit;
}
```
Now we come to the main task function.
It is usually an infinite loop that waits on inputs from something.
In our case, we wait on inputs from the queue.
Our `xQueueReceive` uses the special timeout value `portMAX_DELAY`, which means
that the `xQueueReceive` call will (potentially) block forever and only return
when the queue is not empty.
Other tasks will use integer or zero timeout values
if they have some work to do regardless of whether or not inputs are received.
``` {.c}
static void exampleTask(void* parameters) {
DEBUG_PRINT("Example task main function is running!");
while (true) {
int input;
if (pdTRUE == xQueueReceive(inputQueue, &input, portMAX_DELAY)) {
// Respond to input here!
}
}
}
```
Finally, we implement the public function that is called by other parts of the
system to pass inputs to our new subsystem.
`xQueueOverwrite` specifies that, if the queue is full, we overwrite the
existing contents instead of blocking on the queue's consumer to remove
an item from the other end of the queue.
In subsystems where we do not want to throw away inputs from the queue,
use the `xQueueSend*` family instead.
Subsystems should not expose their queues directly.
It should always be wrapped in a function, like this.
``` {.c}
void exampleTaskEnqueueInput(int value) {
xQueueOverwrite(inputQueue, &value);
}
```
See [the FreeRTOS docs](https://freertos.org/Embedded-RTOS-Queues.html)
for more details on the many `xQueue` API functions available.
> **Design Note:** For complex subsystems, consider implementing the
> algorithmic core as a library that does not depend on FreeRTOS- and
> ARM-related headers, and calling this library from your task.
> This makes it easier to write unit tests for your algorithmic core
> that can be compiled, run, and debugged on a PC.
Writing the public interface
----------------------------
Subsystems should expose a public interface to other parts of the firmware
that hide implementation details as much as is practical.
We create the new file in `src/modules/interface/example.h`:
``` {.c}
#pragma once
#include <stdbool.h>
void exampleTaskInit();
bool exampleTaskTest();
void exampleTaskEnqueueInput(int value);
```
In a real task, make sure to comment the public API thoroughly.
Initializing the task
---------------------
In `src/modules/src/system.c`, make the following changes.
Include the header for our new task:
``` {.c}
#include "example.h"
```
In `systemTask()`, after the lines where the other `Init()` functions
are called, add the line
``` {.c}
exampleTaskInit();
```
In `systemTask()`, after the lines where the other `pass &= ...Test()` lines,
add the line
``` {.c}
pass &= exampleTaskTest();
```
Adding the task to the build
----------------------------
Add this to the Makefile, after the end of the `Modules` block:
``` {.make}
PROJ_OBJ += example.o
```
Compile, flash and run!
-----------------------
Now the last step is to compile and flash your new firmware. Launch the
following commands in a shell:
``` {.bash}
crazyflie-firmware$ make
crazyflie-firmware$ make cload
```
The output will be similar to the following:
``` {.bash}
crazyflie-firmware$ make
(...)
CC hello.o
(...)
Build for the CF2 platform!
Build 22:f8243162f727 (2020.04 +22) MODIFIED
Version extracted from git
Crazyloader build!
Flash | 218132/1032192 (21%), 814060 free | text: 213024, data: 5108, ccmdata: 0
RAM | 71564/131072 (55%), 59508 free | bss: 66456, data: 5108
CCM | 43528/65536 (66%), 22008 free | ccmbss: 43528, ccmdata: 0
crazyflie-firmware$ make cload
../crazyflie-clients-python/bin/cfloader flash cf2.bin stm32-fw
Restart the Crazyflie you want to bootload in the next
10 seconds ...
done!
Connected to bootloader on Crazyflie 2.0 (version=0x10)
Target info: nrf51 (0xFE)
Flash pages: 232 | Page size: 1024 | Buffer pages: 1 | Start page: 88
144 KBytes of flash available for firmware image.
Target info: stm32 (0xFF)
Flash pages: 1024 | Page size: 1024 | Buffer pages: 10 | Start page: 16
1008 KBytes of flash available for firmware image.
Flashing 1 of 1 to stm32 (fw): 161867 bytes (159 pages) ..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10.........9
Reset in firmware mode ...
$
```
Now you can connect your Crazyflie with the client and see the
"Example task main function is running!" in the debug console.
---
title: Unit testing
page_id: unit_testing
---
## Dependencies
Frameworks for unit testing and mocking are pulled in as git submodules.
The testing framework uses ruby and `rake` as well as `libasan` (AddressSanitizer) to generate and run code.
If you run the tests on your own machine you will have to install them.
To minimize the need for installations and configuration, use the docker builder
image (bitcraze/builder) that contains all tools needed. All scripts in the
tools/build directory are intended to be run in the image. The
[toolbelt](https://wiki.bitcraze.io/projects:dockerbuilderimage:index) makes it
easy to run the tool scripts.
## Running all unit tests
With the environment set up locally
make unit
with the docker builder image and the toolbelt
tb make unit
## Running one unit test
When working with one specific file it is often convenient to run only one unit test
make unit FILES=test/utils/src/test_num.c
or with the toolbelt
tb make unit FILES=test/utils/src/test_num.c
## Running unit tests with specific build settings
Defines are managed by make and are passed on to the unit test code. Use the
normal ways of configuring make when running tests. For instance to run test
for Crazyflie 1
make unit LPS_TDOA_ENABLE=1
---
title: Commander
page_id: crtp_commander
---
The commander port is used to send control set-points for the
roll/pitch/yaw/thrust regulators from the host to the Crazyflie. As soon
as the communication link has been established these packets can be sent
and the values are valid until the next packet is received.
Communication protocol
--------------------
+-------+-------+-------+-------+
| ROLL | PITCH | YAW |THRUST |
+-------+-------+-------+-------+
Length 4 4 4 2 bytes
| Name | Byte | Size | Type | Comment|
| --------| -------| ------| -----------| ----------------------|
| ROLL | 0-3 | 4 | float | The pitch set-point|
| PITCH | 4-7 | 4 | float | The roll set-point|
| YAW | 8-11 | 4 | float | The yaw set-point|
| THRUST | 12-13 | 2 | uint16\_t | The thrust set-point|
---
title: Console
page_id: crtp_console
---
This port is used as a one-way text console for printing text from the
Crazyflie to a host using the consoleprintf function.
Communication protocol
======================
Answer (Crazyflie to host):
+---------//-----------+
| PRINTED CONSOLE TEXT |
+---------//-----------+
Length 0-31
The contents of the buffer on the copter side is sent if any of the
following is fulfilled:
- The output buffer (of 31 bytes) is full
- A \"newline\" character has to be send (\\n and/or \\r)
- A flush command as been issued
---
title: Generic Setpoint CRTP Port
page_id: crtp_generic_setpoint
---
This port allows to send setpoints to the platform. The philosophy is to
be able to define setpoint packet format for each different use-case. As
such this is a generic port that has one channel and one main packet
format:
| Port | Channel | Name|
| ------| ---------| --------------------------------------------------|
| 7 | 0 | [Generic setpoint](#generic-setpoint)|
Generic setpoint
----------------
Generic setpoint packet format:
| Byte | Value | Note|
| ------| ---------| ---------------------------|
| 0 |ID | ID of the setpoint packet|
| 1.. | Payload | Format defined per ID|
Defined IDs:
| ID | Type|
| ----| -----------------------------------------------------------------------|
| 0 | [stop](#stop)|
| 1 | [Velocity World](#velocity-world)|
|2 | [Z Distance](#z-distance)|
| 3 | [CPPM Emulation](#cppm-emulation)|
| 4 | [Altitude Hold](#altitude-hold)|
| 5 | [Hover](#hover)|
| 6 | [Full State](#full-state)|
| 7 | [Position](#position)|
### Stop
This is a setpoint with no payload that stops the motors and disables
the control loops. Should be sent when the Crazyflie is landed.
### Velocity World
Velocity setpoint in the world coordinate together with a YAW rotation
speed. Useful for a teleop mode in a local positioning system.
Payload format:
``` {.c}
struct velocityPacket_s {
float vx; // m in the world frame of reference
float vy; // ...
float vz; // ...
float yawrate; // deg/s
} __attribute__((packed));
```
### Z Distance
Set the Crazyflie absolute height and roll/pitch angles. Used for
Z-ranger.
Payload format:
``` {.c}
struct zDistancePacket_s {
float roll; // deg
float pitch; // ...
float yawrate; // deg/s
float zDistance; // m in the world frame of reference
} __attribute__((packed));
```
### CPPM Emulation
CRTP packet containing an emulation of CPPM channels Channels have a
range of 1000-2000 with a midpoint of 1500 Supports the ordinary RPYT
channels plus up to MAX\_AUX\_RC\_CHANNELS auxiliary channels. Auxiliary
channels are optional and transmitters do not have to transmit all the
data unless a given channel is actually in use (numAuxChannels must be
set accordingly)
Current aux channel assignments:
- AuxChannel0: set high to enable self-leveling, low to disable
Payload format:
``` {.c}
#define MAX_AUX_RC_CHANNELS 10
static float s_CppmEmuRollMaxRateDps = 720.0f; // For rate mode
static float s_CppmEmuPitchMaxRateDps = 720.0f; // For rate mode
static float s_CppmEmuRollMaxAngleDeg = 50.0f; // For level mode
static float s_CppmEmuPitchMaxAngleDeg = 50.0f; // For level mode
static float s_CppmEmuYawMaxRateDps = 400.0f; // Used regardless of flight mode
struct cppmEmuPacket_s {
struct {
uint8_t numAuxChannels : 4; // Set to 0 through MAX_AUX_RC_CHANNELS
uint8_t reserved : 4;
} hdr;
uint16_t channelRoll;
uint16_t channelPitch;
uint16_t channelYaw;
uint16_t channelThrust;
uint16_t channelAux[MAX_AUX_RC_CHANNELS];
} __attribute__((packed));
```
### Altitude Hold
Set the Crazyflie vertical velocity and roll/pitch angle.
Payload format:
``` {.c}
struct altHoldPacket_s {
float roll; // rad
float pitch; // ...
float yawrate; // deg/s
float zVelocity; // m/s in the world frame of reference
} __attribute__((packed));
```
### Hover
Set the Crazyflie absolute height and velocity in the body coordinate
system.
Payload format:
``` {.c}
struct hoverPacket_s {
float vx; // m/s in the body frame of reference
float vy; // ...
float yawrate; // deg/s
float zDistance; // m in the world frame of reference
} __attribute__((packed));
```
### Full State
Set the full state.
Payload format:
``` {.c}
struct fullStatePacket_s {
int16_t x; // position - mm
int16_t y;
int16_t z;
int16_t vx; // velocity - mm / sec
int16_t vy;
int16_t vz;
int16_t ax; // acceleration - mm / sec^2
int16_t ay;
int16_t az;
int32_t quat; // compressed quaternion, see quatcompress.h
int16_t rateRoll; // angular velocity - milliradians / sec
int16_t ratePitch; // (NOTE: limits to about 5 full circles per sec.
int16_t rateYaw; // may not be enough for extremely aggressive flight.)
} __attribute__((packed));
```
#### Position
Set the absolute postition and orientation.
``` {.c}
struct positionPacket_s {
float x; // Position in m
float y;
float z;
float yaw; // Orientation in degree
} __attribute__((packed));
```
---
title: Localization CRTP port
page_id: crtp_localizaton
---
This port groups various packets related to localization. It exposes two
channels:
| Port | Channel | Name|
| ------| ---------| ----------------------|
| 6 | 0 | External Position|
| 6 | 1 | Generic localization|
External Position
-----------------
This packet is used to send the Crazyflie position as acquired by an
external system. The main use it to send the position acquired by a
motion capture system to push it in the Extended Kalman Filter to allow
the Crazyflie to calculate an estimate and control its state.
The packet format is:
``` {.c}
struct CrtpExtPosition
{
float x; // in m
float y; // in m
float z; // in m
} __attribute__((packed));
```
Generic Localization
--------------------
This channel intends to host packets useful for the localization
subsystem. It has been created to serve the Loco Positioning System
packets but can be used for more general things like GPS NMEA or binary
streams. The format of the packet is:
| Byte | Value | Note|
| ------| ---------| ---------------------------------------|
| 0 | ID | ID of the packet|
| 1.. | Payload | Packet payload. Format defined per ID|
| ID | Packet |
| ----| ------------------------------|
| 2 | LPP Short packet tunnel|
| 3 | Enable emergency stop|
| 4 | Reset emergency stop timeout|
### LPP Short packet tunnel
Packet used to send LPP short packet to the loco positioning system. The
payload is sent to the sytem as an [LPP Short
Packet](https://www.bitcraze.io/documentation/repository/lps-node-firmware/master/protocols/lpp/).
### Emergency stop
When received, the stabilizer loop is set in emergency stop mode which
stops all the motors. The loop stays in emergency stop mode until the
situation is reset.
### Reset emergency stop timeout
At startup the emergency stop timeout is disabled.
The first time this packet is receive, the emergency stop timeout is
enabled with a timeout of 1 second.
This packet should then be sent, and received by the Crazyflie, at least
once every 1 second otherwise the stabilizer loop will be set in
emergency stop and all motors will stop.
---
title: The Lighthouse positioning system
page_id: lh_overview
redirects:
- /docs/functional-areas/lighthouse_overview/
---
The Lighthouse positioning system uses the HTC Vive base stations (aka Lighthouse) togeather with the Lighthouse
deck to achieve high precision positioning.
The basics:
* [System overview](/docs/functional-areas/lighthouse/system_overview.md)
* [Limitations](/docs/functional-areas/lighthouse/limitations.md)
* [Positioning methods](/docs/functional-areas/lighthouse/positioning_methods.md)
Development related pages
* [Terminology and definitions](/docs/functional-areas/lighthouse/terminology_definitions.md)
* [Kalman estimator measurement model](/docs/functional-areas/lighthouse/kalman_measurement_model.md)
* [Converting between LH1 and LH2 angles](/docs/functional-areas/lighthouse/angle_conversion.md)
---
title: Lighthouse limitations
page_id: lh_limitations
---
One limitation of the lighthouse deck is that since the deck only has horizontal sensors, the angle at which the base-stations are seen cannot be too shallow. This means that you should fly at least 40cm bellow the base-stations and that the base-stations should be placed above the flight space.
## State of the base station V2 support
The lighthouse V2 support is currently at a Minimum Viable Product state.
This means that is it well supported but still has some limitation that can be lifted in future development.
* 1 and 2 base stations are supported
* The base stations must be configured to use channel 1 and 2