This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
projects:crazyflie:firmware:comm_protocol [2012-07-30 15:25] macke |
projects:crazyflie:firmware:comm_protocol [2021-06-24 16:49] (current) kimberly |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | <WRAP center round important 60%> | ||
+ | This page has deprecated and will be archived. Please go to [[https:// | ||
+ | </ | ||
====== Overview ====== | ====== Overview ====== | ||
- | ===== CRTP? ===== | + | CRTP is the protocol used to communicate |
- | The CRTP (Crazy RealTime Protocol) | + | |
- | * [[comm_protocol# | + | |
- | * [[comm_protocol# | + | |
- | * [[comm_protocol# | + | |
- | * ... | + | |
- | ====== Communication ====== | + | CRTP is implemented in 3 layers: |
- | ===== Packet structure ===== | + | |
- | The CRTP packet consists of 32 bytes of data: | + | |
- | < | + | |
- | +------+------+ | + | |
- | | PORT | DATA | | + | |
- | +------+------+ | + | |
- | | PORT | <31 | | + | |
- | +------+------+ | + | |
- | 1 | + | |
- | </ | + | |
- | The ports numbers are composed of: Priority, task number and message number. | + | < |
- | * The priority is set by the 2 MSB of the port number. It permit to each task to chose in a per message basis the priority of its messages | + | |
- | * The task number is used by CRTP to distribute the messages to the different tasks in the copter | + | |
- | * Finally the message number is composed by the two LSB and permit to have 4 different communication channel per task. | + | +-----------------------+ |
+ | | CRTP packets handling | | ||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
- | A proposed notation | + | * **CRTP Link** |
+ | * **CRTP Packet handling** delivers the packet to the right subsystem in the copter and in the PC control software. | ||
+ | * **Application/ | ||
+ | |||
+ | Implemented link drivers: | ||
+ | ^ **Link** | ||
+ | | [[comm_protocol# | ||
+ | | [[comm_protocol# | ||
+ | | [[comm_protocol# | ||
+ | |||
+ | Current port allocation: | ||
+ | ^ **Port** | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | |||
+ | ====== Communication ====== | ||
+ | ===== Packet structure ===== | ||
+ | A CRTP packet consists of a 8bit header followed by 0-31 bytes of data. | ||
< | < | ||
+ | 7 | ||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | ||
- | | P | + | | Port |
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | DATA 0 | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | : | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | DATA 30 | ||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | ||
- | #define PORT(P,T,N) ((P<< | ||
</ | </ | ||
- | **NOTE:** This is currently being changed! | + | ^ **Field** ^ **Byte** ^ **Bit** ^ |
+ | | | ||
+ | | ::: | | ||
+ | | ::: | | ||
+ | | Data | ||
+ | |||
+ | A port maps to a major function in the Crazyflie that is normally implemented as a separate task. When a CRTP packet is received in the Crazyflie the packet | ||
===== Physical layers ===== | ===== Physical layers ===== | ||
Line 38: | Line 64: | ||
==== 2.4 GHz NordicSemi Radio ==== | ==== 2.4 GHz NordicSemi Radio ==== | ||
- | < | + | The wireless |
- | Wireless: | + | |
- | +------+------+ | + | |
- | | PORT | DATA | | + | |
- | +------+------+ | + | |
- | | PORT | <31 | | + | |
- | +------+------+ | + | |
- | 1 | + | |
- | The wireless | + | |
- | </ | + | |
==== USB port ==== | ==== USB port ==== | ||
+ | **TODO** | ||
==== Serial port ==== | ==== Serial port ==== | ||
+ | The serial port is configured in 115200 8N1. CRTP packets are sent and received asynchronously using the following packet format: | ||
+ | |||
< | < | ||
- | Serial port: | + | 7 |
- | +-------+------+--------+------+-----+ | + | +---+---+---+---+---+---+---+---+ |
- | | START | PORT | LENGTH | + | | |
- | +-------+------+--------+------+-----+ | + | +---+---+---+---+---+---+---+---+ |
- | | 0xAAAA| PORT | < | + | | 0xAA |
- | +-------+------+--------+------+-----+ | + | +---+---+---+---+---+---+---+---+ |
- | | + | | |
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | : : | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | DATA 30 | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Cksum | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | |||
+ | +--------+--------+--------+--------+--------+--....--+--------+ | ||
+ | | | ||
+ | +--------+--------+--------+--------+--------+--....--+--------+ | ||
</ | </ | ||
+ | ^ **Field** ^ **Byte** ^ **Bit** ^ | ||
+ | | | ||
+ | | | ||
+ | | ::: | | ||
+ | | ::: | | ||
+ | | Size | ||
+ | | Data | ||
+ | | | ||
+ | === Examples === | ||
+ | To send setpoints to the [[projects: | ||
+ | < | ||
+ | 0xaa 0xaa 0x30 0x0e 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x3e | ||
+ | </ | ||
+ | |||
+ | To ping Crazyflie: | ||
+ | < | ||
+ | | ||
+ | < | ||
+ | </ | ||
===== Ports ===== | ===== Ports ===== | ||
- | | *Port* | ||
- | | [[comm_protocol# | ||
- | | [[comm_protocol# | ||
- | | [[comm_protocol# | ||
- | | 0: | ||
- | | [[comm_protocol# | ||
- | | 3: | ||
- | | 3: | ||
- | | 3: | ||
- | | 3: | ||
- | ==== Console | + | ==== Logging |
+ | The purpose of the logging is to be able to log variables that are available in the copter during runtime. The available variables are listed using a TOC that can be read from the copter. A logging block can then be registered consisting of there variables and the data will be sent periodically via CRTP to a receiver. | ||
- | This port is used as a simulation | + | ^ **Port** |
+ | | | ||
+ | | | ||
+ | | | ||
- | The packet format contains only the datas to send/ | + | === Table of content access (Port 5 channel 0) === |
+ | This channel is used to access | ||
+ | |||
+ | == Messages == | ||
+ | Each message uses an additional command byte that is followed by 0 to 31 bytes of data depending of the command. For every command byte there' | ||
+ | |||
+ | The logging variables are requested by the receiver until all variables are returned. When the variable index is out of range, empty reply is returned | ||
+ | |||
+ | The CRC32 is a hash of the copter' | ||
+ | |||
+ | The following messages are sent from the Client to the Crazyflie: | ||
+ | ^ **Request for** ^ **Byte** | ||
+ | | TOC item | | ||
+ | | ::: | ||
+ | | TOC CRC and count | 0 | 0x01 (CMD_GET_INFO) Request the TOC CRC and item count | | ||
+ | |||
+ | The following messages are sent from the Crazyflie to the Client: | ||
+ | ^ **Reply for** ^ **Byte** | ||
+ | | TOC item | ||
+ | | ::: | ||
+ | | ::: | ||
+ | | ::: | ||
+ | | ::: | ||
+ | | TOC CRC and count | | ||
+ | | ::: | ||
+ | | ::: | ||
+ | | ::: | ||
+ | | ::: | ||
+ | |||
+ | == Usage == | ||
+ | Example of checking the CRC of a TOC to determine if the TOC needs to be refreshed. | ||
< | < | ||
- | +--------+ | + | |
- | | Data | | + | -------- |
- | +--------+ | + | Get TOC CRC32 ---> |
- | 1-31 :bytes | + | < |
+ | [Compare CRC] | ||
</ | </ | ||
- | From the copter side a _fair_ behavior should be to have a buffer and to send a new packet if at least one of the 3 following condition is fullfil: | + | Example |
- | * The output buffer (of 31bytes) | + | < |
- | * A " | + | |
- | * A flush command as been issued | + | |
+ | Request for TOC item 0 | ||
+ | < | ||
+ | Request for TOC item 1 | ||
+ | < | ||
+ | | ||
+ | | ||
+ | Request for TOC item N-1 ---> | ||
+ | where N is Number of | ||
+ | total variables in TOC | ||
+ | < | ||
+ | [optional] | ||
+ | Request for TOC item N | ||
+ | | ||
+ | <--- Reply with length 1, byte 0x00 identifying TOC request returned | ||
+ | [Fetch complete] | ||
+ | </ | ||
- | ==== Parameters | + | === Log settings access (Port 5 channel 1) === |
+ | This channel is used to access the log settings to add/ | ||
+ | |||
+ | == Messages == | ||
+ | The following messages are sent from the Client to the Crazyflie: | ||
+ | ^ **Request for** ^ **Byte** | ||
+ | | Create a new log block | ||
+ | | ::: | | ||
+ | | ::: | 2-31 | [[comm_protocol# | ||
+ | | Append to existing log block | ||
+ | | ::: | | ||
+ | | ::: | 2-31 | [[comm_protocol# | ||
+ | | Delete a log block | ||
+ | | ::: | | ||
+ | | Start a log block | ||
+ | | ::: | | ||
+ | | ::: | | ||
+ | | Stop a log block | ||
+ | | ::: | | ||
+ | | Reset log | ||
+ | |||
+ | |||
+ | |||
+ | The response for all of the above messages is sent from the Crazyflie to the Client: | ||
+ | ^ **Byte** | ||
+ | | | ||
+ | | | ||
+ | | | ||
- | The parameters system aims at making accessible all the gettable and settable parameters of the copter. In the copter a table of parameters is hold and can be retrieved. In this table every parameter name is associated with an ID and a group name. Three ID are used to acces the TOC and the paramareters: | ||
- | | **Port** | + | == Variable format == |
- | | (0, | + | The following format is used to identify a variable that is to be logged from the Crazyflie |
- | | (0, | + | |
- | | (0, | + | |
- | === TOC access === | + | Log Type represents type of value sent in packet. Logged value is converted to this type before storing into log packet. Upper bytes will be discarded if Log Type is integer and value does not fit. |
- | This ports permits to access the parameters table of content. The first byte of the message | + | |
- | | *Message ID* | *Meaning in upstream packets* | *Meaning in downstream packets* | | + | ^ |
- | | | + | | |
- | | | + | | 2 |
- | | | + | | |
+ | | 4 | ||
+ | | | ||
+ | | 6 | int32_t | ||
+ | | | ||
+ | | 8 | ||
- | The upstream ID are commands and are sent alone. The downstream | + | ^ **Storage Type** |
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | |||
+ | TOC variable request (Storage type is ignored, it is taken from Crazyflie internal TOC): | ||
+ | < | ||
+ | 7 | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Storage type | Log type | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Variable ID | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | </ | ||
+ | |||
+ | Arbitrary memory address request: | ||
+ | < | ||
+ | 7 | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Storage type | Log type | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | 0xff | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Mem Address 0 | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Mem Address 1 | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Mem Address 2 | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | | Mem Address 3 | | ||
+ | +---+---+---+---+---+---+---+---+ | ||
+ | </ | ||
+ | |||
+ | |||
+ | == List of return codes ( errno.h codes are used, returned values are positive ) == | ||
+ | ^ **Error** | ||
+ | | 0 | No error | | ||
+ | | ENOENT (2) | Block or variable not found | | ||
+ | | E2BIG (7) | Log block is too long | | ||
+ | | ENOEXEC (8) | Unknown command received | ||
+ | | ENOMEM (12) | No memory to allocate Log Block or Log Item | | ||
+ | |||
+ | == Usage == | ||
+ | Adding a new log block with id 0x0a with variable 0x55 type uint32_t and variable 0x66 type float32 to the settings: | ||
+ | < | ||
+ | | ||
+ | | ||
+ | Add log block ---> | ||
+ | < | ||
+ | [DONE] | ||
+ | |||
+ | Packet structure: | ||
+ | Computer -> CF : 0x[5,1] 0x00 0x0a 0x03 0x55 0x07 0x66 | ||
+ | CF -> Computer : 0x[5,1] 0x00 0x0a 0x00 | ||
+ | </ | ||
+ | |||
+ | Deleting an existing log block 0x55 from the settings: | ||
+ | < | ||
+ | | ||
+ | | ||
+ | Delete log packet | ||
+ | < | ||
+ | [DONE] | ||
+ | |||
+ | Packet structure: | ||
+ | Computer -> CF : 0x[5,1] 0x02 0x55 | ||
+ | CF -> Computer : 0x[5,1] 0x02 0x55 0x00 | ||
+ | </ | ||
+ | |||
+ | === Log data access (Port 5 channel 2) === | ||
+ | Logging data is sent back to the copter as raw data with only the block id. This means that the lookup of what data is for what variable has to be done on the computer side. Log | ||
+ | block header contains 3 byte timestamp, its value is number of microseconds from Crazyflie system start (it will wrap around in about 16 seconds. Is is also currently based on xTaskGetTickCount, | ||
+ | |||
+ | ^ **Byte** | ||
+ | | | ||
+ | | 1-3 | Block send time timestamp in us, LSB first | | ||
+ | | 4-31 | Logged variable values, LSB first | | ||
+ | |||
+ | < | ||
+ | Adding a log block 0xbb at 100ms interval logging variable ID 0x55 of type uint16: | ||
+ | Computer -> CF : 0x[5,1] 0x00 0xbb 0x02 0x55 // create logging block | ||
+ | CF -> Computer : 0x[5,1] 0x00 0x55 0x00 // OK | ||
+ | Computer -> CF : 0x[5,1] 0x03 0xbb 0x0A // start sending block with 100ms interval | ||
+ | CF -> Computer : 0x[5,1] 0x03 0x55 0x00 // OK | ||
+ | |||
+ | Receiving a log block 0xbb with timestamp 130.532s (0x1FDE4 ms), logging uint16 variable with value 0xBABE: | ||
+ | CF -> Computer : 0x[5,2] 0xBB 0xE4 0xFD 0x01 0xBE 0xBA | ||
+ | </ | ||
+ | ==== Parameters ==== | ||
+ | The parameters system makes all the gettable and settable parameters of the copter accessible. The copter holds a table of parameters which can be retrieved. In this table every parameter name is associated with an ID and a group name. Three IDs are used to acces the TOC and the parameters: | ||
+ | |||
+ | ^ Port ^ Channel | ||
+ | | 2 | 0 | TOC access | ||
+ | | 2 | 1 | Parameter read | | ||
+ | | 2 | 2 | Parameter write | | ||
+ | |||
+ | === TOC access (Port 2 channel 0) === | ||
+ | These messages permit to access the parameters table of content. The first byte of the message is a message ID, three messages ID are defined: | ||
+ | |||
+ | ^ Message ID ^ Meaning in upstream packets | ||
+ | | 0 | Reset TOC pointer | ||
+ | | 1 | Get next TOC element | ||
+ | | 3 | Get TOC CRC32 | Number of parameters, TOC CRC32 | | ||
+ | |||
+ | The upstream ID are commands and are sent alone. The downstream | ||
< | < | ||
Line 122: | Line 355: | ||
</ | </ | ||
- | The parameters are sequentially requested by the PC until the end. When the last parameter is reached it has the ID 0 'Last TOC element' | + | The parameters are sequentially requested by the PC until the end. When the last parameter is reached it has the ID 0 'Last TOC element' |
- | The CRC32 is a hash of the copter TOC. This is aim at implementing caching of the TOC in the PC Utils to avoid fetching the full TOC each time the copter is connected. | + | The CRC32 is a hash of the copter TOC. This is aimed at implementing caching of the TOC in the PC Utils to avoid fetching the full TOC each time the copter is connected. |
- | === Parameter read === | + | === Parameter read (Port 2 channel 1) and parameter write (Port 2 channel 2)=== |
- | === Parameter write === | + | The following messages are sent from the client to the Crazyflie: |
+ | ^ **Request for** | ||
+ | | Parameter read | | ||
+ | | Parameter write | ||
+ | | ::: | ||
+ | |||
+ | The following messages are sent from the Crazyflie to the client: | ||
+ | ^ **Reply for** ^ **Byte** | ||
+ | | Parameter read & write | ||
+ | | ::: | ||
+ | |||
+ | === Fight control ==== | ||
+ | **TODO** | ||
+ | |||
+ | === Link layer === | ||
+ | | 3: | ||
+ | | 3: | ||
+ | | 3: | ||
+ | | 3: |