|
|
|
# Ports
|
|
|
|
|
|
|
|
* `ROBOT_SDK_PORT_MIN = 10100`
|
|
|
|
* `ROBOT_SDK_PORT_MAX = 10500`
|
|
|
|
* `ROBOT_DEVICE_PORT = 20020`
|
|
|
|
* `ROBOT_PROXY_PORT = 30030`
|
|
|
|
* `ROBOT_BROADCAST_PORT = 40927`
|
|
|
|
* `ROBOT_DEFAULT_WIFI_ADDR = 192.168.2.1`
|
|
|
|
|
|
|
|
# Direct WIFI connection
|
|
|
|
|
|
|
|
Send a `SetSdkConnection` message to `192.168.2.1:30030` containing local IP
|
|
|
|
address (`0.0.0.0` is fine) and a random port between `10100` and `10500`. The
|
|
|
|
Robomaster responds with a state, which should be 2, and the IP address
|
|
|
|
`192.168.2.24` that the client should use. The client will then send further
|
|
|
|
messages to `192.168.2.1:20020` via `192.168.2.24:<random port>`.
|
|
|
|
|
|
|
|
# Commands
|
|
|
|
|
|
|
|
* UTF-8 encoded
|
|
|
|
* command
|
|
|
|
* version
|
|
|
|
* quit
|
|
|
|
|
|
|
|
[1]: https://github.com/dji-sdk/RoboMaster-SDK/blob/v0.1.2/sample_code/RoboMasterEP/connection/network/robot_connection.py
|
|
|
|
[2]: https://github.com/SMerrony/tello/blob/master/messages.go
|
|
|
|
|
|
|
|
# Message Format
|
|
|
|
|
|
|
|
All big-endian unless otherwise noted.
|
|
|
|
|
|
|
|
## Header
|
|
|
|
|
|
|
|
The preamble `0x55` indicates the start of every message and is part of the
|
|
|
|
message header along with the length and a checksum of the header. A header is
|
|
|
|
always 4 bytes long.
|
|
|
|
|
|
|
|
| bytes | description |
|
|
|
|
|-------|-------------|
|
|
|
|
| 1 | `0x55` preamble |
|
|
|
|
| 2 | length of message |
|
|
|
|
| 1 | 8-bit CRC |
|
|
|
|
|
|
|
|
The CRC is a checksum of the preamble and message length together. The length
|
|
|
|
in bytes is of the entire message including the header.
|
|
|
|
|
|
|
|
## Body
|
|
|
|
|
|
|
|
The data is always at least one byte.
|
|
|
|
|
|
|
|
| bytes | description |
|
|
|
|
|-------|-------------|
|
|
|
|
| 1 | sender |
|
|
|
|
| 1 | receiver |
|
|
|
|
| 2 | seq ID |
|
|
|
|
| 1 | attri |
|
|
|
|
| 1 | cmdset |
|
|
|
|
| 1 | cmdid |
|
|
|
|
| >1 | data |
|
|
|
|
| 2 | 16-bit CRC |
|
|
|
|
|
|
|
|
The last two bits of the attri byte starting from the LSB represent if the
|
|
|
|
message is an ack and if an ack is needed. The other bits in the byte are
|
|
|
|
unused. Any request can specify if an ack is required, or not. If no ack is
|
|
|
|
required, the drone will not send a response.
|
|
|
|
|
|
|
|
| bit | set | unset |
|
|
|
|
|-----|-------------|-------|
|
|
|
|
| 8 | is ack | enc |
|
|
|
|
| 7 | ack needed | no ack needed |
|
|
|
|
|
|
|
|
### TODO
|
|
|
|
|
|
|
|
* What is a seq ID?
|
|
|
|
* What is the format of sender and receiver?
|
|
|
|
* may not actually matter
|
|
|
|
* index always seems to be 0
|
|
|
|
* `index * 32 + host`
|
|
|
|
* sender is `_client.hostbyte`
|
|
|
|
* What is the difference between cmdid and cmdset?
|
|
|
|
|
|
|
|
# Messages
|
|
|
|
|
|
|
|
| name | cmdset | cmdid | bytes |
|
|
|
|
|------|--------|--------|-------|
|
|
|
|
| led | `0x3f` | `0x33` | 15 |
|
|
|
|
| set sdk connection | `0x3f` | `0xd4` | 10 |
|
|
|
|
|
|
|
|
## SetSdkConnection
|
|
|
|
|
|
|
|
| bytes | description |
|
|
|
|
|-------|-------------|
|
|
|
|
| 1 | control |
|
|
|
|
| 1 | host |
|
|
|
|
| 1 | connection |
|
|
|
|
| 1 | protocol |
|
|
|
|
| 4 | IP address |
|
|
|
|
|
|
|
|
Response message.
|
|
|
|
|
|
|
|
| bytes | description |
|
|
|
|
|-------|-------------|
|
|
|
|
| 1 | Return code |
|
|
|
|
| 1 | state |
|
|
|
|
| 4 | IP address |
|
|
|
|
|
|
|
|
What is `config_ip`? What is `state`?
|
|
|
|
|
|
|
|
## LED
|
|
|
|
|
|
|
|
| bytes | description |
|
|
|
|
|-------|-------------|
|
|
|
|
| 4 | comp mask |
|
|
|
|
| 2 | LED mask |
|
|
|
|
| 1 | ctrl & effect mode |
|
|
|
|
| 1 | red |
|
|
|
|
| 1 | green |
|
|
|
|
| 1 | blue |
|
|
|
|
| 1 | loop |
|
|
|
|
| 2 | t1 |
|
|
|
|
| 2 | t2 |
|
|
|
|
|
|
|
|
Control and effect modes share one byte, in MSB and LSB respectively.
|