Start
Connect to the aircraft
Usually you do not have to do anything. Corvus looks for a link when it starts and takes the first one it finds. This page explains how it chooses, how to connect by hand, how to share the link with a second ground station, and how to read the status bar once you are connected.
Automatic connection
At launch Corvus goes through this list and takes the first rule that produces a link:
- A connection on the command line. Only a person types one, so it outranks any hardware.
- A flight controller on a USB cable, recognised by its USB descriptor.
- A SiK telemetry radio, recognised as a USB serial adapter (FTDI, CP210x or CH340).
- The connection saved in the config file, used exactly as written.
- The ground station UDP port,
udp:0.0.0.0:14550. This is where PX4 SITL publishes, so a simulator connects with no clicking either.
The LINK tab says which rule won, with an AUTO chip beside the
status, and AUTO · SCANNING while it is still looking. Serial
ports are never opened just to find out what is behind them: the choice is
made from the USB descriptors alone. Some ports are left out before any rule
sees them:
- Phantom ports that exist whether or not anything is plugged in, such as
/dev/ttyS*on Linux. - A board in its bootloader, which speaks the bootloader protocol rather than MAVLink and is about to be wanted by the firmware flasher.
- An RTK base station. On Linux a u-blox receiver on USB looks exactly like a flight controller's port, and it never sends a heartbeat. Corvus recognises it and leaves it to the RTK service.
With two devices of the same kind, the first by device name wins, so the same aircraft is picked on every launch regardless of the order in which USB happened to enumerate them.
What it will not do
- It never takes a link that is up. Plug a second device in while connected and the LINK tab offers it as a row with a Connect button instead of switching, because the link it would replace may be carrying an aircraft that is flying. It only dials by itself when the current link is down and has had no heartbeat for 8 seconds.
- Your choice wins for the session. Once you connect or disconnect by hand, nothing is dialled automatically until the next launch. Then it starts fresh, so tomorrow's cable wins again on its own. The one thing it still does is follow the device you chose when it comes back under a new port name (see below).
- It never takes a radio another vehicle's link holds. With one radio per vehicle (see One radio per vehicle) auto-connect drives the main link only, and a plugged-in radio can be opened as a link of its own with Open as another vehicle instead of replacing the main one.
- It never picks PX4's onboard ports (14540 to 14549), which belong to MAVSDK and MAVROS. A saved connection on one of them is honoured but warned about.
Unplugging a device and plugging it back in counts as asking again: if the link is down, it will be dialled.
Plugging it into a different USB socket can give the same device a new port
name (a new COM number on Windows, a new /dev/cu.usbserial name
on macOS, ttyACM1 instead of ttyACM0 on Linux after
a quick replug). Corvus recognises the device by its USB vendor, product and
serial number and moves the link to the new name at the same baud rate,
within a few seconds, also when you connected by hand. With two identical
devices that carry no serial number it cannot tell which one is yours, and
leaves the choice to you.
To switch any part of it off, add an autoconnect block to ~/.corvus/config.json. Every key is optional and must be a real true or false:
{ "autoconnect": { "enabled": true, "usb": true, "sik": true, "udp_fallback": true } }
The complete contract (every reason string, the state fields and the endpoints) is in the auto-connect interface reference.
Connecting by hand
Open the LINK tab in the side panel. This is the normal way to override the automatic choice; a command-line connection is only for scripting. Serial and UDP/TCP share one card and one Connect button. The switch at the top chooses which, and it opens on the kind you connected with last.
- Serial
-
Choose the port from the dropdown and a baud rate. The list is read again every time you open the tab, so a radio plugged in after launch simply appears. 57600 is the default, labelled for the Holybro SiK Radio V3.
The port you last flew on stays in the list even when it is unplugged, marked not connected, so an empty dropdown is never the whole answer.
- UDP and TCP
-
Type a connection string, or use one of the presets for the endpoints PX4 publishes. Presets fill the field rather than connecting outright, so you can edit before you commit.
udp:andudpin:bind a local port and wait for the aircraft to speak.udpout:dials out and speaks first. This is what a mavlink-routerUdpEndpointinMode = Serverneeds, and what reaches a router behind NAT.tcp:connects to aTcpEndpoint;tcpin:listens for one.
- Recent connections
- At the top of the tab, one click to reuse. They are kept exact:
:57600and:115200on the same port are two entries, because merging them would silently reconnect at the wrong baud rate. The newest one is also the tab's memory, so a laptop opened at the field is one button away from the link it had. - Disconnect
- Frees the radio without quitting the app. It also works during a connection attempt, which is exactly when a retry loop needs stopping. After a disconnect nothing reconnects behind your back.
SiK radios, simulators and ROS
Holybro SiK Telemetry Radio V3
On Linux the radio shows up as two devices, for example /dev/ttyUSB0 and /dev/ttyUSB1. The lower numbered one is the MAVLink data port.
| Setting | Value |
|---|---|
| Device path | /dev/ttyUSB0 (the lower of the two) |
| Baud rate | 57600 (factory default) |
| Connection string | serial:/dev/ttyUSB0:57600 |
On a serial link Corvus asks for conservative MAVLink stream rates so a 57 kbps radio is not saturated, allows a longer heartbeat timeout (10 s), and reconnects with backoff if the link drops. To program the radios themselves (network ID, air rate, power), see Telemetry radio.
PX4 SITL
PX4's simulator sends to UDP 14550, which Corvus listens on by default. Start it and Corvus connects:
make px4_sitl # in the PX4-Autopilot directory
Next to MAVROS, MAVSDK or ROS
Those use UDP 14540, PX4's onboard link, which is a different socket from the 14550 one Corvus uses. Only one process can hold a UDP port, so pointing Corvus at 14540 while MAVROS runs (or the other way round) leaves one of them with no telemetry at all. On a simulator that looks like a broken vehicle rather than a port clash, which is why Corvus names the conflict when the bind fails. Leave Corvus on 14550. If both really need the same endpoint, put a mavlink-router in front and give each its own port.
Running QGroundControl at the same time
A serial port, a USB autopilot or a SiK radio can be opened by exactly one program, so a second ground station has always meant closing the first. It does not have to. Tick Mirror this link over UDP on the LINK tab, then start QGroundControl. There is nothing to configure on either end and nothing to install: 14550 is the UDP link QGroundControl opens by itself, Corvus mirrors every frame there from the first one, and the router is part of Corvus and stops when Corvus does.
Why Corvus listens on 14551
Corvus deliberately does not bind 14550 itself. It listens on 14551 and speaks first. QGroundControl's default link binds 14550 and waits to be spoken to, so a Corvus binding it too would leave two listeners and no talker. On Linux the second bind fails and QGroundControl has no link. On macOS both binds succeed and one socket silently receives every datagram, so QGroundControl shows a connected link that receives nothing and neither program reports an error. If something else holds 14551, Corvus takes any free port instead and says which on the LINK tab.
With PX4 SITL, pick another port. SITL also sends to UDP 14550, so a Corvus listening there that also mirrors to 127.0.0.1:14550 would be mirroring into its own vehicle link. Corvus skips that target and says so on the LINK tab. Set the forwarding port to 14560 (or any free port) and add a UDP link on that port in QGroundControl.
Letting the second station command
By default the second station is a screen: telemetry flows out to it and nothing flows back. Let it command the aircraft is a separate switch, because two stations that can both arm and both change mode is a hazard rather than a convenience, and only you know whether you want it. Turn it on and QGroundControl's frames reach the aircraft unchanged (mission uploads, mode changes, parameter writes), and Corvus still records the whole stream to its tlog.
Give QGroundControl its own system ID
Corvus identifies itself as system 254, component 190. PX4 counts message sequence numbers per system ID, so two stations sharing one make the autopilot report packet loss that is not happening, and blur which station a GCS failsafe is about. In QGroundControl set Application Settings, MAVLink, Ground Station system ID to something else; 255 is a fine choice. If you forget, the LINK tab says so: Corvus notices a second station sending as 254, names the setting to change, and does not pass that station's frames to the aircraft until it has its own ID.
What Corvus reads off a shared link
Whether you share the link this way or put mavlink-router in front of it, the link then carries more than the aircraft: the other station's heartbeat, a companion computer, a gimbal, sometimes a second vehicle. Corvus reads only its own aircraft. Another node's heartbeat cannot change the armed state or the flight mode, and cannot keep a lost aircraft looking connected. The aircraft to command is taken from the first heartbeat sent by an actual autopilot, not the first heartbeat of any kind. An identical frame arriving twice within 0.3 s (the signature of a routing loop) is dropped before it is read, so a looped acknowledgement cannot confirm a command twice. Another autopilot on the link is ignored: one link is one vehicle, and a second vehicle needs a link of its own; see Several vehicles.
One Corvus at a time
Starting Corvus while it is already running shows a message saying so,
including where the first one is listening, rather than opening a second
window. The reason is the same as above: a serial port can be used by exactly
one program, but on Linux and macOS the operating system does not enforce
it. Two copies both open /dev/ttyUSB0 without an error and each
reads whatever bytes it gets to first. Both windows then show the same
aircraft with half its telemetry missing: attitude updates while position
freezes, and a command's acknowledgement arrives in the other window.
Neither reports a disconnect, because from each program's point of view
nothing failed.
If you really want two (two aircraft, two radios, two separate links on one
laptop), set CORVUS_ALLOW_MULTI=1. Give the second one its own
connection string and its own forwarding port. They still cannot share a
radio, and they will write over each other's settings.
CORVUS_ALLOW_MULTI=1 ./run.sh
The guard is a lock the operating system holds for the running process, not a file left on disk, so a Corvus that crashed or was force quit leaves nothing to clean up. The next launch just works.
Reading the status bar
Next to the connection state you get link quality, not only "connected": signal strength, heartbeat regularity and receive errors. Connected tells you the socket is up; link quality tells you whether it is worth flying on.
| State | What you see |
|---|---|
| Connecting or reconnecting | Yellow dot, with the last error |
| Connected | Green dot |
| Disconnected | Grey dot |
| Ready to fly | READY in a green pill: the autopilot's own preflight checks pass |
| Armed, on the ground | ARMED in an amber pill: propellers are live and the aircraft is still within reach |
| Airborne | FLYING in a blue pill, from the vehicle's own EXTENDED_SYS_STATE, or from height above home on firmware that does not send it |
| Preflight failing | Amber NOT READY: the autopilot would refuse to arm. The failing checks are counted beside it and listed on hover, and Corvus asks the autopilot for them when it has not said |
| Readiness not reported | Grey STANDBY: firmware that does not publish its preflight state |
| Kill switch engaged | KILL SWITCH in a red pill, shown above ARMED and FLYING. PX4 still reports armed while the switch holds the motors, so the bar says what the motors are actually doing. A switch that was already engaged when Corvus connected is recognised too, by the preflight check it fails |
| Flight termination | TERMINATED in a red pill: the vehicle reports termination or lockdown and has not said why. The motor outputs are cut |
The three states worth recognising at a glance (cleared to fly, propellers live, airborne) carry a tinted pill as well as a colour, so they can be told apart by shape before the colour is read. NOT READY deliberately gets no pill: it is the absence of a clearance, not an active state.
Notifications, toasts and the kill switch messages are explained on Map, HUD and flight controls.