-
Notifications
You must be signed in to change notification settings - Fork 198
Overview and Concepts
- High-Level Control: We call a controller that takes a state estimate and a reference state to control the position and velocity of a quadrotor high-level controller. In our framework this is the position controller which outputs so called control commands.
- Low-Level Control: The low-level controller receives the control commands from the high-level controller through a so called bridge and controls either body rates or attitude. In our case this is implemented in the Betaflight Firmware.
- Autopilot: The autopilot contains a position controller and a state machine and executes whatever the user requests form the quadrotor, such as going to a pose or executing a trajectory, etc.
- Bridge: A bridge is the interface between the autopilot and a low-level controller. In our framework, the SBUS bridge is the interface that takes control command messages from the autopilot and communicates them as SBUS messages to an FPV flight controller which runs a low-level controller in its Betaflight Firmware.
You have to provide a state estimate in form of a nav_msgs/Odometry message to the autopilot/state_estimate
topic. Note that the autopilot's behavior changes during start and land depending on the frame_id
set in the odometry message's header as described below.
Also not that the high-level control loop of the autopilot is triggered by the state estimate so it needs to be throttled to a desired rate as described below.
As the name suggests, the autopilot controls a quadrotor for you and accepts various user inputs. It contains a state machine that switches states depending on the action it should execute. It will not allow you to switch between different command inputs in an unsafe way, e.g. it rejects any other commands while it is executing a trajectory. When it is done with executing a certain action it goes back to a hover state. The autopilot contains a position controller which implements the methods presented in our RA-L 18 paper.
-
autopilot/state_estimate (nav_msgs/Odometry)
The state estimate has to be provided as an Odometry message. The autopilot has different behaviour depending on the
header/frame_id
field. If the field isvision
, the autopilot goes directly to hover upon receiving astart
command. Upon receiving aland
command it goes straight down with a constant velocity forever or until stopped. For any otherframe_id
the autopilot assumes that the ground is at zero height and does a take off routine upon receiving astart
command if the quadrotor starts below a certain height threshold and goes directly to hover otherwise. Upon receiving aland
, for a non visionframe_id
the autopilot makes the quadrotor go down to an almost zero height and then ramps down the propellers and switches off. -
low_level_feedback (quadrotor_msgs/LowLevelFeedback)
The low-level feedback is received from the bridge and contained in the autopilot feedback that is published by the autopilot. It also tells the autopilot if the quadrotor was taken over manually by a remote control.
-
autopilot/pose_command (geometry_msgs/PoseStamped)
Commands the autopilot to go to the requested pose in world coordinates. The autopilot generates a polynomial trajectory with constant heading rate to the target location and executes it.
-
autopilot/velocity_command (geometry_msgs/TwistStamped)
Command the autopilot to apply a certain velocity in world coordinates. To avoid jumps this input is filtered.
-
autopilot/reference_state (quadrotor_msgs/TrajectoryPoint)
If desired one can generate a trajectory in world coordinates, sample it, and send it to this topic at the sampling frequency. It is recommended to send the entire trajectory instead.
-
autopilot/trajectory (quadrotor_msgs/Trajectory)
On this topic, entire trajectories in world coordinates can be sent to the autopilot. Upon receiving a trajectory, the autopilot starts executing it. It rejects trajectories that start from a position too far away from the current position. The autopilot keeps a queue of trajectories so while it is executing a trajectory, new trajectory segments can be sent to the autopilot which are executed consecutively but only if there are no position jumps in between them.
-
autopilot/control_command_input (quadrotor_msgs/ControlCommand)
This enables to compute control commands and have the autopilot feed them through to the bridge. In the default parameters, this feature is disabled.
-
autopilot/start (std_msgs/Empty)
Sends a start command. The behavior depends on the available state estimate (see above).
-
autopilot/force_hover (std_msgs/Empty)
Forces the autopilot to abort any action and go to a hover state. This also empties the trajectory queue.
-
autopilot/land (std_msgs/Empty)
Sends a land command. The behavior depends on the available state estimate (see above).
-
autopilot/off (std_msgs/Empty)
Sends an off command. At any point this stops the motors of the quadrotors immediately. Be careful, when used in mid air the quadrotor will fall out of the sky!
-
control_command (quadrotor_msgs/ControlCommand)
Control command that is sent to the bridge.
-
autopilot/feedback (quadrotor_msgs/AutopilotFeedback)
Feedback message that is e.g. subscribed to by the quadrotor gui to display feedback as described in Basic Usage.
-
The control loop of the autopilot is triggered by receiving a state estimate message. This enables having a minimum latency from measurement to control action. Therefore, the state estimate has to be throttled down to the desired rate at which the control should run. Attention: Be careful when using a topic_tools/throttle for this since you might end up with the wrong message rate as e.g. discussed in this issue.
-
Since you can send sampled trajectories to the autopilot, the sampling frequency might not match the frequency of the state estimate and therefore of the control loop. The autopilot therefore linearly interpolates between the trajectory samples.
The autopilot helper is a class that should be used for any interaction of a custom node with the autopilot. It contains a subscriber to the autopilot feedback and publishers to all the topics the autopilot subscribes to. The autopilot helper provides methods to get basically any information that is contained in the autopilot feedback message and it provides methods to send any kind of command that the autopilot accepts, such as velocity commands, pose commands, trajectories etc.
Check out our integration test for examples how the autopilot helper can be used.
A bridge is the interface that communicates control commands from the autopilot to the low level controller, such as our SBUS bridge that communicates with an FPV flight controller. The interaction with the bridge happens to through ROS topics with the following conventions:
-
bridge/arm (std_msgs/Bool)
In order to be allowed to forward control commands to the low-level controller, a bridge needs to once receive a boolean which is true on this topic.
-
control_command (quadrotor_msgs/ControlCommand)
These are the control commands published by the autopilot.
-
battery_voltage (std_msgs/Float32)
The bridge should receive the measured battery voltage on this topic as a float value. In our case this is published by our voltage reader in case of measuring the battery voltage by an ADC on an onboard single board computer.
-
low_level_feedback (quadrotor_msgs/LowLevelFeedback)
This message contains all relevant feedback from the low level controller. It is also subscribed to by the autopilot and later contained in the autopilot feedback message published by the autopilot.
Additionally, the SBUS bridge publishes the received SBUS commands from an RC receiver but they are only used as potential feedback and are not required by our framework. If you implement your own bridge, obey these conventions to ensure compatibility with our framework.
We provide a small trajectory generation framework, which is mostly used to generate polynomial trajectories. It is in a state where it should be re-implemented from scratch but ain't nobody got time for this? If you do, send me a pull request.
To generate trajectories, use the trajectory generation helpers which return sampled trajectories as trajectory objects. These can then e.g. directly be sent to the autopilot by calling the autopilot helper's sendTrajectory method. Additionally to polynomials, the helpers allow you to design circle trajectories (check out its implementation for explanations of the parameters). Both of these trajectory helpers do not fill the orientation and heading fields of the sampled trajectory points! You can add a heading trajectory to an existing trajectory object with the heading trajectory helper.
The manual flight assistant receives inputs from a joypad or a remote control to command the autopilot with velocity commands as described in Basic Usage.
-
joy (sensor_msgs/Joy)
Published by a joy node and used to manually command velocities to the quadrotor.
-
received_sbus_message (sbus_bridge/SbusRosMessage)
Published by the SBUS bridge and can be used to command the quadrotor as with a joypad with a remote control.
- autopilot/start (std_msgs/Empty)
Sends a start command to the autopilot. (Mapped as described in Basic Usage)
- autopilot/land (std_msgs/Empty)
Sends a land command to the autopilot. (Mapped as described in Basic Usage)
- autopilot/velocity_command (geometry_msgs/TwistStamped)
Sends velocity commands to the autopilot.