diff --git a/docs/developer-guide/firmware/code-architecture.md b/docs/developer-guide/firmware/code-architecture.md index a915055..0d601bc 100644 --- a/docs/developer-guide/firmware/code-architecture.md +++ b/docs/developer-guide/firmware/code-architecture.md @@ -89,7 +89,7 @@ Its main purpose is to handle the interaction between offboard commands and the ### Controller The controller uses the inputs from the command manager and estimator to compute a control output. -This control output is computed in a generic form (\(x\), \(y\), and \(z\) torques, and force \(F\)), and is later converted into actual motor commands by the mixer. +This control output is computed in a generic form (\(Q_x\), \(Q_y\), and \(Q_z\) torques, and forces \(F_x, F_y,\) and \(F_z\)), and is later converted into actual motor commands by the mixer. ### Mixer -The mixer takes the generic outputs computed by the controller and maps them to actual motor commands depending on the configuration of the vehicle. +The mixer takes the outputs computed by the controller and maps them to actual motor commands depending on the configuration of the vehicle. diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md index ff62948..d286351 100644 --- a/docs/user-guide/getting-started.md +++ b/docs/user-guide/getting-started.md @@ -2,14 +2,14 @@ Reading through the pages in this user guide in order should provide you with the information you need to get a vehicle flying with ROSflight. The following is a summary of the steps you'll need to follow to get your vehicle set up, with links to the corresponding documentation pages: - 1. [Set up your hardware](hardware-setup.md) (fixed-wing or multirotor platform, flight controller, and companion computer) - 2. [Flash your flight controller with the latest ROSflight firmware](flight-controller-setup.md) - 3. [Set up your RC transmitter](rc-configuration.md) - 4. [Set up ROS2 on your companion computer](ros2-setup.md) - 5. [Configure the flight controller for your setup](parameter-configuration.md): the configuration checklists below should help guide you through this process - 6. [Run through your preflight checks](preflight-checks.md) - 7. [Tune the firmware attitude controller gains](improving-firmware-performance.md) (multirotors only) - 8. [Set up autonomous flight via offboard control](autonomous-flight.md) (optional) + 1. [Hardware setup](hardware-setup.md): Set up your hardware (fixed-wing or multirotor platform, flight controller, and companion computer) + 2. [Flight controller setup](flight-controller-setup.md): Flash your flight controller with the latest ROSflight firmware. + 3. [RC Configuration](rc-configuration.md): Set up your RC transmitter. + 4. [ROS2 setup](ros2-setup.md): Set up ROS2 on your companion computer. + 5. [Parameter configuration](parameter-configuration.md): Configure the flight controller for your setup. The configuration checklists below should help guide you through this process. + 6. [Preflight checks](preflight-checks.md): Run through your preflight checks + 7. [Improving firmware performance](improving-firmware-performance.md) (multirotors only): Tune the firmware attitude controller gains + 8. [Autonomous flight](autonomous-flight.md) (optional): Set up autonomous flight via offboard control ## Configuration Checklist @@ -19,7 +19,7 @@ The following checklists should help you get a new vehicle set up for the first 1. Set the `FIXED_WING` parameter (`1` if a fixed-wing, `0` if a multirotor) 2. Set the `RC_TYPE` parameter (`0` if PPM, `1` if SBUS) - 3. Set the `MIXER` parameter to the appropriate value described in the [Hardware Setup](hardware-setup.md) page + 3. Set the `PRIMARY_MIXER` parameter to the appropriate value described in the [Hardware Setup](hardware-setup.md) page 4. Set the `MOTOR_PWM_UPDATE` parameter (typically `490` for SimonK ESCs, `50` for standard servos) 5. Make sure your [RC transmitter is set up correctly](rc-configuration.md) 6. Set up your RC switches @@ -38,7 +38,7 @@ The following checklists should help you get a new vehicle set up for the first 1. Calibrate ESCs 1. Make sure `MOTOR_MIN_PWM` and `MOTOR_MAX_PWM` are correct (usually `1000` and `2000`) - 2. Set `MIXER` param to `0` (ESC calibration mixer) + 2. Set `PRIMARY_MIXER` param to `0` (ESC calibration mixer) 3. Set `ARM_SPIN_MOTORS` to `0` 4. Perform ESC calibration. For standard ESCs: @@ -47,14 +47,14 @@ The following checklists should help you get a new vehicle set up for the first 3. Connect power to the motors 4. Drop the throttle to minimum - 5. Set the `MIXER` parameter back to the appropriate value for your vehicle (see the [Hardware Setup](hardware-setup.md#motor-layouts) page) + 5. Set the `PRIMARY_MIXER` parameter back to the appropriate value for your vehicle (see the [Hardware Setup](hardware-setup.md#motor-layouts) page) 6. Set `ARM_SPIN_MOTORS` back to `1` 2. The `ARM_SPIN_MOTORS` parameter should be set to `1` so the motors spin slowly when armed. The idle throttle setting can be adjusted with the `MOTOR_IDLE_THR` parameter. 3. You'll most likely want to set the `CAL_GYRO_ARM` param to `1` to enable calibrating gyros before arming 4. Set the `RC_ATT_MODE` parameter to set RC control mode (`0` for rate mode, `1` for angle mode [default]) 5. Set torque offsets as described in the [RC trim calculation](improving-firmware-performance.md#rc-trim) section of the Improving Firmware Performance page - 6. Set the `FAILSAFE_THR` parameter to specify the throttle level the MAV will hold if the transimtter disconnects. Set the parameter to `0` if you just want the MAV to drop, otherwise determine the amount of throttle required to hover the MAV and set the parameter comfortably below that. DO NOT set it above, as this will result in a runaway MAV. We recommended that you test the throttle level in an enclosed space by powering off the transmitter while hovering, if you set this parameter above 0. + 6. Set the `FAILSAFE_THR` parameter to specify the throttle level the MAV will hold if the transmitter disconnects. Set the parameter to `0` if you just want the MAV to drop, otherwise determine the amount of throttle required to hover the MAV and set the parameter comfortably below that. DO NOT set it above, as this will result in a runaway MAV. We recommended that you test the throttle level in an enclosed space by powering off the transmitter while hovering, if you set this parameter above 0. 6. Tune the controller gains as described in the [Multirotor gain tuning](improving-firmware-performance.md#gain-tuning) section of the Improving Firmware Performance page ### Fixed-Wing-Specific Setup diff --git a/docs/user-guide/hardware-setup.md b/docs/user-guide/hardware-setup.md index 8ad61d1..2203c6f 100644 --- a/docs/user-guide/hardware-setup.md +++ b/docs/user-guide/hardware-setup.md @@ -2,7 +2,10 @@ ## Parts List -To use ROSflight to its full potential, you will need the following system components. Some components are mounted on your MAV (Miniature Aerial Vehicle), while others are on the ground. ROSflight supports both multirotor and fixed-wing vehicles. +To use ROSflight to its full potential, you will need the following system components. +Some components are mounted on your MAV (Miniature Aerial Vehicle), while others are on the ground. +ROSflight supports both multirotor and fixed-wing vehicle types. + *Mounted on the MAV* @@ -23,7 +26,8 @@ To use ROSflight to its full potential, you will need the following system compo ### Frame, Motors, ESCs, Battery, and Propeller -We do not officially support any specific multirotor or airplane frame, motor, ESC, Battery or Propeller combination. There are a lot of great resources for building your own MAV, and there are a lot of great kits out there that have all of these parts. +We do not officially support any specific multirotor or airplane frame, motor, ESC, Battery or Propeller combination. +There are a lot of great resources for building your own MAV, and there are a lot of great kits out there that have all of these parts. If you are designing your own multirotor or airplane, you may want to look at [ecalc](https://www.ecalc.ch/), an online tool which can help you design a proper ESC/Battery/Motor/Propeller system for your MAV. @@ -31,7 +35,7 @@ Some things to keep in mind as you design or build your MAV. * Most kits do not include space for a companion computer, cameras, laser scanners or other sensors. Be sure to think about where these components are going to go, and how their placement will affect the CG of the MAV. * You will likely also need to customize the power circuitry of your MAV to provide power to your companion computer at some specific voltage. Many people like to separate the power electronics (the ESCs and motors), from the computer and companion sensors. This can really come in handy if you are trying to develop code on the MAV, because you can have the computer on and sensors powered, and not worry at all about propellers turning on and causing injury as you move the aircraft about by hand. We will talk about this more when we talk about wiring up your MAV. -* Cheap propellers can cause a huge amount of vibration. Consider buying high-quality propellers, doing a propeller balance, or both. RCGroups, DIY Drones and Youtube have some awesome guides on how to do propeller balancing. +* Cheap propellers can cause a huge amount of vibration. Consider buying high-quality propellers, doing a propeller balance, or both. RCGroups, DIY Drones and YouTube have some awesome guides on how to do propeller balancing. * ESCs will need to be calibrated from 2000 to 1000 us @@ -73,6 +77,7 @@ You will need Wi-Fi to communicate with your MAV when it is in the air. Because For RC Control, you will need a transmitter with between 6 and 8 channels. Any additional channels will be wasted. We require RC control for safe operation, and only support arming and disarming via RC control. + ROSflight only supports PPM (pulse position modulation) and SBUS receivers. Individual channel PWM outputs are not supported. Any configurations with PPM or SBUS and 6-8 channels will be sufficient. ### Laptop or Base Station Computer @@ -87,23 +92,42 @@ A joystick is used for [software-in-the-loop (SIL) simulations](running-gazebo-s A battery monitor is an analog sensor that provides battery voltage and/or battery current information. This data can be used to prevent power loss in air or to measure system load. The sensor outputs an analog voltage proportional to the battery voltage and/or current through the battery. Most flight controllers come equipped with a built-in battery monitor, but if not, small PCB sensors are also available that can be connected to the flight controller. + For ROSflight to use a battery monitor, an appropriate multiplier must be set. ROSflight multiplies the analog signal from the monitor by the multiplier to get the final reading. The monitor datasheet should contain the information needed to get the multiplier. For example, the datasheet for the AttoPilot 50V/90A sensor states that it outputs 63.69 mV / V. To get the original battery voltage, the multiplier must be 1/.06369, or 15.7. The multipliers for the voltage and current are set separately, with the `BATT_VOLT_MULT` and `BATT_CURR_MULT` parameters, respectively. ROSflight applies a simple low-pass filter to remove noise from the voltage and current measurements. These filters are configurable via the `BATT_VOLT_ALPHA` and `BATT_CURR_ALPHA` [parameters](parameter-configuration.md). The alpha value for a given cutoff frequency \\(a\\), can be calulated with: \\( \alpha = e ^ {-.01a} \\). As battery voltages do not typically change quickly, the default of 0.995 usually suffices. -More information on battery monitor hardware, including determinining appropriate multipliers and creating a simple DIY monitor, can be found on the [OpenPilot Wiki](https://opwiki.readthedocs.io/en/latest/user_manual/revo/voltage_current.html). + +More information on battery monitor hardware, including determining appropriate multipliers and creating a simple DIY monitor, can be found on the [OpenPilot Wiki](https://opwiki.readthedocs.io/en/latest/user_manual/revo/voltage_current.html). ## Wiring Diagram + Below is an example wiring diagram for a multirotor using an MSI Cubi as a companion computer. This diagram also includes the motor power switch, which allows for the sensors, flight controller, and companion computer to be powered on while the motors are off. This is a safer way to test sensors, code, etc. as the motors are unable to spin while the switch is off. ![Wiring Diagram](images/Wiring_Diagram.png) Your needs will likely be slightly different than what is shown. This is meant as an example only and can be adapted to fit your needs. -## Motor Layouts +## Motor Layouts and Mixer + +The mixer takes in the desired forces and torques from the firmware controller and computes the motor and servo outputs accordingly. +If it is not set correctly, it will likely lead to a crash. +Make sure it is set properly for your airframe! + +!!! tip "Quick Start" + + For a quick start, use one of the "canned mixers". + For a more accurate mixer, use a custom mixer. + +ROSflight offers some pre-computed, "canned" mixers that can be used off the shelf for a variety of common multirotor and fixedwing airframes. +These mixers do not take into account all the parameters of your system (i.e. motor and propeller parameters), so they will be less accurate than they could be. +If you want a more accurate mixer, or have easy access to the motor and prop parameters of your system, then we recommend using a custom mixer. -The desired mixer can be chosen by setting the `MIXER` parameter to the following values: +!!! note + A mixer must be chosen for the firmware to allow arming. + +The desired mixer can be chosen by setting the `PRIMARY_MIXER` parameter to one of the following values: | # | Mixer | |---|---------| @@ -116,16 +140,104 @@ The desired mixer can be chosen by setting the `MIXER` parameter to the followin | 6 | Octo X | | 7 | Y6 | | 8 | X8 | -| 9 | Tricopter | -| 10 | Fixed-wing (traditional AETR) | +| 9 | Fixed-wing (traditional AETR) | +| 10 | Inverted V-tail fixedwing (like the RMRC Anaconda frame) | +| 11 | Custom mixer | The associated motor layouts are shown below for each mixer. The **ESC calibration** mixer directly outputs the throttle command equally to each motor, and can be used for calibrating the ESCs. ![Mixer_1](images/mixers_1.png) -![Mixer_2](images/mixers_2.png) +The following parameters related to the mixer are optional: + +* `SECONDARY_MIXER` +* `USE_MOTOR_PARAM` +* All the custom mixer params of the form `PRI_MIXER_i_j` or `SEC_MIXER_i_j` + +The following subsections have more detail on these parameters. + +### Secondary Mixer + +ROSflight also has a secondary mixer that can be set using the options in the above table by setting the `SECONDARY_MIXER` param. + +Offboard control commands will use the secondary mixer, while commands from the RC safety pilot will use the primary mixer. +Thus, both RC throttle and attitude override will affect the mixer, as shown in the following image. + +![RC Mixer Configuration](images/rc_mixer_configuration.png) + +The `mixer_to_use_` structure represents the mixer that will be used when computing the output. +The header, which includes the default PWM rate and the output type for each output channel, is always set to the same as the primary mixer. +See [Defining a Custom Mixer](#defining-a-custom-mixer) for more information. +Note that if the `SECONDARY_MIXER` param is not set, then it will default to the same value as the primary mixer. + +The secondary mixer might be useful when the airframe needs a different mixer for the offboard control (from the companion computer) than for RC control (from the safety pilot). +It allows flexibility for more advanced mixing schemes while still having a functional mixer available to a safety pilot. + +### Using Motor Parameters + +The parameter `USE_MOTOR_PARAM` causes the firmware to compute the actuator outputs differently than if `USE_MOTOR_PARAM` is set false. +As described in _Small Unmanned Aircraft: Theory and Practice_ by Beard and McLain, the mixing matrix is formed using equations from propeller theory, resulting in a set of equations that set the desired forces and torques equal to the square of the angular speeds of the propellers. +If the motor and propeller parameters are known, then the desired voltage (and thus throttle) setting can be computed from the squared angular speeds. + +If the motor and propeller parameters are not known, then some simplifying assumptions are made to compute the desired throttle settings for each motor from the desired forces and torques. +See [the report on the ROSflight mixer derivation](https://github.com/rosflight/rosflight_docs/blob/main/latex-reports/mixer.tex) for more information on the mixer derivation and assumptions. + +!!! tip "Quick Start" + + If using a canned mixer, set `USE_MOTOR_PARAM=0`. + + If using a custom mixer, set `USE_MOTOR_PARAM=1` **only** if the mixer was designed with motor parameters. + +The canned mixing matrices assume that `USE_MOTOR_PARAM` parameter is set to false. +Using a canned mixer matrix and setting `USE_MOTOR_PARAM=1` (i.e. specifying that you want to mix with motor and propeller parameters) will cause the outputs to be scaled incorrectly. +It is not required to use motor and propeller parameters when using a custom mixing matrix, but make sure your custom mixer makes sense. + +Also, if you selected a custom mixer and used the motor parameters to generate the mixer, make sure you set `USE_MOTOR_PARAM=1`. Otherwise, the outputs will likely be scaled incorrectly. + +!!! Important + + We recommend flying your firmware in simulation _before_ loading the firmware onto real hardware to make sure everything is working. + +!!! Warning + + It is not recommended to use a _canned mixer for the primary mixer_ and a _custom mixer for the secondary mixer_ **when the secondary mixer needs `USE_MOTOR_PARAM=1`.** + In other words, both `PRIMARY_MIXER` and `SECONDARY_MIXER` should use motor parameters, or neither should. + + This is important because the canned mixers make assumptions that affect the gains of the controller on the aircraft. + This means that a canned mixer will require slightly different tuning than a custom mixer might. + +### Defining a Custom Mixer + +A custom mixer can be defined by: + +1. Set `PRIMARY_MIXER` (required) and/or `SECONDARY_MIXER` (optional) to the desired value in the mixer table +2. Load the mixing matrix parameters for either the primary or the secondary mixer + +Note that computing the parameters of the mixing matrix is done on the companion computer. + +The firmware loads a custom mixer by loading all the values from parameters. +Since there are 6 inputs to the mixer (\(F_x,F_y,F_z,Q_x,Q_y,Q_z\)) and 10 possible outputs, the mixer is a 6x10 matrix and there are 60 parameters associated with each custom mixer. +For a standard quadrotor, however, most of these would be zero, since only the first 4 outputs (columns of the mixer matrix) would be used. + +In addition to the parameters associated with the 6x10 mixing matrix, there are two additional sets of parameters that need to be defined for each output used, the `PRI_MIXER_OUT_i` and the `PRI_MIXER_PWM_i` parameters, which define the output type and the default PWM rate, respectively, for the `i`th output. +See the [Parameter Configuration Page](parameter-configuration.md) for more information on these parameters. + +The recommended way to load a custom mixer is to first compute all the required parameters and save them to a file on the companion computer. +The parameters are named `PRI_MIXER_i_j` or `SEC_MIXER_i_j`, where `(i,j)` is the index of the parameter in the 6x10 mixing matrix. +See the [Parameter Configuration Page](parameter-configuration.md) for more information on these parameters. +A convenience script is available in the `roscopter` ROS2 package that will compute the custom mixer and save the parameter values in a format ready to load. + +Once the parameters are saved to a file, load them with the ROS2 service call (make sure `rosflight_io` is running): +```ros2 service call /param_load_from_file rosflight_msgs/srv/ParamFile "{file: absolute/or/relative/path/to/saved/param/file.yaml}"``` + +Also make sure to save those parameters to memory with the ROS2 service call: +```ros2 service call /param_write std_srvs/srv/Trigger``` + + +!!! Important + Test your mixer in simulation first when making changes, to avoid accidents. ## Connecting to the Flight Controller diff --git a/docs/user-guide/images/mixers_1.png b/docs/user-guide/images/mixers_1.png index 97a44b9..52a5c2a 100644 Binary files a/docs/user-guide/images/mixers_1.png and b/docs/user-guide/images/mixers_1.png differ diff --git a/docs/user-guide/images/mixers_2.png b/docs/user-guide/images/mixers_2.png deleted file mode 100644 index 0ae2403..0000000 Binary files a/docs/user-guide/images/mixers_2.png and /dev/null differ diff --git a/docs/user-guide/images/rc_mixer_configuration.png b/docs/user-guide/images/rc_mixer_configuration.png new file mode 100644 index 0000000..e3361e5 Binary files /dev/null and b/docs/user-guide/images/rc_mixer_configuration.png differ diff --git a/docs/user-guide/parameter-configuration.md b/docs/user-guide/parameter-configuration.md index 781e7d5..e59aaa0 100644 --- a/docs/user-guide/parameter-configuration.md +++ b/docs/user-guide/parameter-configuration.md @@ -109,21 +109,157 @@ This is a list of all ROSflight parameters, including their types, default value |-----------|-------------|------|---------------|-----|-----| | BAUD_RATE | Baud rate of MAVlink communication with companion computer | int | 921600 | 9600 | 921600 | | SERIAL_DEVICE | Serial Port (for supported devices) | int | 0 | 0 | 3 | +| AIR_DENSITY | Density of the air (kg/m^3) | float | 1.225f | 0 | 1000.0 | +| NUM_MOTORS | Number of vertical-facing motors on the vehicle | int | 4 | 1 | 8 | +| MOTOR_RESISTANCE | Electrical resistance of the motor windings (ohms) | float | 0.042f | 0 | 1000.0 | +| MOTOR_KV | Back emf constant of the motor in SI units (V/rad/s) | float | 0.01706f | 0 | 1000.0 | +| NO_LOAD_CURRENT | No-load current of the motor in amps | float | 1.5 | 0 | 1000.0 | +| PROP_DIAMETER | Diameter of the propeller in meters | float | 0.381f | 0 | 1.0 | +| PROP_CT | Thrust coefficient of the propeller | float | 0.075f | 0 | 100.0 | +| PROP_CQ | Torque coefficient of the propeller | float | 0.0045f | 0 | 100.0 | +| VOLT_MAX | Maximum voltage of the battery (V) | float | 25.0f | 0 | 100.0 | +| USE_MOTOR_PARAM | Flag to use motor parameters in the mixer | int | false | 0 | 1 | +| PRI_MIXER_OUT_0 | Output type of mixer output 0. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_1 | Output type of mixer output 1. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_2 | Output type of mixer output 2. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_3 | Output type of mixer output 3. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_4 | Output type of mixer output 4. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_5 | Output type of mixer output 5. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_6 | Output type of mixer output 6. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_7 | Output type of mixer output 7. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_8 | Output type of mixer output 8. | int | 0 | 0 | 1 | +| PRI_MIXER_OUT_9 | Output type of mixer output 9. | int | 0 | 0 | 1 | +| PRI_MIXER_PWM_0 | PWM frequenct output for mixer output 0 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_1 | PWM frequenct output for mixer output 1 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_2 | PWM frequenct output for mixer output 2 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_3 | PWM frequenct output for mixer output 3 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_4 | PWM frequenct output for mixer output 4 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_5 | PWM frequenct output for mixer output 5 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_6 | PWM frequenct output for mixer output 6 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_7 | PWM frequenct output for mixer output 7 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_8 | PWM frequenct output for mixer output 8 | float | 0 | 0 | 490 | +| PRI_MIXER_PWM_9 | PWM frequenct output for mixer output 9 | float | 0 | 0 | 490 | +| PRI_MIXER_0_0 | Value of the custom mixer at element [0,0] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_0 | Value of the custom mixer at element [1,0] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_0 | Value of the custom mixer at element [2,0] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_0 | Value of the custom mixer at element [3,0] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_0 | Value of the custom mixer at element [4,0] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_0 | Value of the custom mixer at element [5,0] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_1 | Value of the custom mixer at element [0,1] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_1 | Value of the custom mixer at element [1,1] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_1 | Value of the custom mixer at element [2,1] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_1 | Value of the custom mixer at element [3,1] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_1 | Value of the custom mixer at element [4,1] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_1 | Value of the custom mixer at element [5,1] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_2 | Value of the custom mixer at element [0,2] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_2 | Value of the custom mixer at element [1,2] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_2 | Value of the custom mixer at element [2,2] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_2 | Value of the custom mixer at element [3,2] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_2 | Value of the custom mixer at element [4,2] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_2 | Value of the custom mixer at element [5,2] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_3 | Value of the custom mixer at element [0,3] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_3 | Value of the custom mixer at element [1,3] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_3 | Value of the custom mixer at element [2,3] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_3 | Value of the custom mixer at element [3,3] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_3 | Value of the custom mixer at element [4,3] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_3 | Value of the custom mixer at element [5,3] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_4 | Value of the custom mixer at element [0,4] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_4 | Value of the custom mixer at element [1,4] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_4 | Value of the custom mixer at element [2,4] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_4 | Value of the custom mixer at element [3,4] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_4 | Value of the custom mixer at element [4,4] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_4 | Value of the custom mixer at element [5,4] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_5 | Value of the custom mixer at element [0,5] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_5 | Value of the custom mixer at element [1,5] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_5 | Value of the custom mixer at element [2,5] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_5 | Value of the custom mixer at element [3,5] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_5 | Value of the custom mixer at element [4,5] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_5 | Value of the custom mixer at element [5,5] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_6 | Value of the custom mixer at element [0,6] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_6 | Value of the custom mixer at element [1,6] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_6 | Value of the custom mixer at element [2,6] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_6 | Value of the custom mixer at element [3,6] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_6 | Value of the custom mixer at element [4,6] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_6 | Value of the custom mixer at element [5,6] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_7 | Value of the custom mixer at element [0,7] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_7 | Value of the custom mixer at element [1,7] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_7 | Value of the custom mixer at element [2,7] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_7 | Value of the custom mixer at element [3,7] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_7 | Value of the custom mixer at element [4,7] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_7 | Value of the custom mixer at element [5,7] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_8 | Value of the custom mixer at element [0,8] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_8 | Value of the custom mixer at element [1,8] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_8 | Value of the custom mixer at element [2,8] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_8 | Value of the custom mixer at element [3,8] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_8 | Value of the custom mixer at element [4,8] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_8 | Value of the custom mixer at element [5,8] | float | 0.0f | -inf | inf | +| PRI_MIXER_0_9 | Value of the custom mixer at element [0,9] | float | 0.0f | -inf | inf | +| PRI_MIXER_1_9 | Value of the custom mixer at element [1,9] | float | 0.0f | -inf | inf | +| PRI_MIXER_2_9 | Value of the custom mixer at element [2,9] | float | 0.0f | -inf | inf | +| PRI_MIXER_3_9 | Value of the custom mixer at element [3,9] | float | 0.0f | -inf | inf | +| PRI_MIXER_4_9 | Value of the custom mixer at element [4,9] | float | 0.0f | -inf | inf | +| PRI_MIXER_5_9 | Value of the custom mixer at element [5,9] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_0 | Value of the custom mixer at element [0,0] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_0 | Value of the custom mixer at element [1,0] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_0 | Value of the custom mixer at element [2,0] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_0 | Value of the custom mixer at element [3,0] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_0 | Value of the custom mixer at element [4,0] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_0 | Value of the custom mixer at element [5,0] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_1 | Value of the custom mixer at element [0,1] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_1 | Value of the custom mixer at element [1,1] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_1 | Value of the custom mixer at element [2,1] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_1 | Value of the custom mixer at element [3,1] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_1 | Value of the custom mixer at element [4,1] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_1 | Value of the custom mixer at element [5,1] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_2 | Value of the custom mixer at element [0,2] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_2 | Value of the custom mixer at element [1,2] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_2 | Value of the custom mixer at element [2,2] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_2 | Value of the custom mixer at element [3,2] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_2 | Value of the custom mixer at element [4,2] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_2 | Value of the custom mixer at element [5,2] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_3 | Value of the custom mixer at element [0,3] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_3 | Value of the custom mixer at element [1,3] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_3 | Value of the custom mixer at element [2,3] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_3 | Value of the custom mixer at element [3,3] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_3 | Value of the custom mixer at element [4,3] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_3 | Value of the custom mixer at element [5,3] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_4 | Value of the custom mixer at element [0,4] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_4 | Value of the custom mixer at element [1,4] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_4 | Value of the custom mixer at element [2,4] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_4 | Value of the custom mixer at element [3,4] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_4 | Value of the custom mixer at element [4,4] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_4 | Value of the custom mixer at element [5,4] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_5 | Value of the custom mixer at element [0,5] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_5 | Value of the custom mixer at element [1,5] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_5 | Value of the custom mixer at element [2,5] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_5 | Value of the custom mixer at element [3,5] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_5 | Value of the custom mixer at element [4,5] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_5 | Value of the custom mixer at element [5,5] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_6 | Value of the custom mixer at element [0,6] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_6 | Value of the custom mixer at element [1,6] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_6 | Value of the custom mixer at element [2,6] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_6 | Value of the custom mixer at element [3,6] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_6 | Value of the custom mixer at element [4,6] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_6 | Value of the custom mixer at element [5,6] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_7 | Value of the custom mixer at element [0,7] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_7 | Value of the custom mixer at element [1,7] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_7 | Value of the custom mixer at element [2,7] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_7 | Value of the custom mixer at element [3,7] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_7 | Value of the custom mixer at element [4,7] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_7 | Value of the custom mixer at element [5,7] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_8 | Value of the custom mixer at element [0,8] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_8 | Value of the custom mixer at element [1,8] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_8 | Value of the custom mixer at element [2,8] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_8 | Value of the custom mixer at element [3,8] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_8 | Value of the custom mixer at element [4,8] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_8 | Value of the custom mixer at element [5,8] | float | 0.0f | -inf | inf | +| SEC_MIXER_0_9 | Value of the custom mixer at element [0,9] | float | 0.0f | -inf | inf | +| SEC_MIXER_1_9 | Value of the custom mixer at element [1,9] | float | 0.0f | -inf | inf | +| SEC_MIXER_2_9 | Value of the custom mixer at element [2,9] | float | 0.0f | -inf | inf | +| SEC_MIXER_3_9 | Value of the custom mixer at element [3,9] | float | 0.0f | -inf | inf | +| SEC_MIXER_4_9 | Value of the custom mixer at element [4,9] | float | 0.0f | -inf | inf | +| SEC_MIXER_5_9 | Value of the custom mixer at element [5,9] | float | 0.0f | -inf | inf | | SYS_ID | Mavlink System ID | int | 1 | 1 | 255 | -| STRM_HRTBT | Rate of heartbeat stream (Hz) | int | 1 | 0 | 1000 | -| STRM_STATUS | Rate of status stream (Hz) | int | 10 | 0 | 1000 | -| STRM_ATTITUDE | Rate of attitude stream (Hz) | int | 200 | 0 | 1000 | -| STRM_IMU | Rate of IMU stream (Hz) | int | 250 | 0 | 1000 | -| STRM_MAG | Rate of magnetometer stream (Hz) | int | 50 | 0 | 75 | -| STRM_BARO | Rate of barometer stream (Hz) | int | 50 | 0 | 100 | -| STRM_AIRSPEED | Rate of airspeed stream (Hz) | int | 50 | 0 | 50 | -| STRM_SONAR | Rate of sonar stream (Hz) | int | 40 | 0 | 40 | -| STRM_SERVO | Rate of raw output stream | int | 50 | 0 | 490 | -| STRM_RC | Rate of raw RC input stream | int | 50 | 0 | 50 | -| STRM_GNSS | Maximum rate of GNSS data streaming. Higher values allow for lower latency| int | 1000 | 0 | 1000 | -| STRM_GNSS_FULL | Maximum rate of fully detailed GNSS data streaming | int | 0 | 0 | 10 | -| STRM_BATTERY | Rate of battery status stream | int | 0 | 0 | 50 -| PARAM_MAX_CMD | saturation point for PID controller output | float | 1.0 | 0 | 1.0 | | PID_ROLL_RATE_P | Roll Rate Proportional Gain | float | 0.070f | 0.0 | 1000.0 | | PID_ROLL_RATE_I | Roll Rate Integral Gain | float | 0.000f | 0.0 | 1000.0 | | PID_ROLL_RATE_D | Roll Rate Derivative Gain | float | 0.000f | 0.0 | 1000.0 | @@ -145,12 +281,12 @@ This is a list of all ROSflight parameters, including their types, default value | PID_TAU | Dirty Derivative time constant - See controller documentation | float | 0.05f | 0.0 | 1.0 | | MOTOR_PWM_UPDATE | Overrides default PWM rate specified by mixer if non-zero - Requires reboot to take effect | int | 0 | 0 | 490 | | MOTOR_IDLE_THR | min throttle command sent to motors when armed (Set above 0.1 to spin when armed) | float | 0.1 | 0.0 | 1.0 | -| FAILSAFE_THR | Throttle sent to motors in failsafe condition (set just below hover throttle) | float | 0.3 | 0.0 | 1.0 | +| FAILSAFE_THR | Throttle sent to motors in failsafe condition (set just below hover throttle) | float | -1.0 | 0.0 | 1.0 | | ARM_SPIN_MOTORS | Enforce MOTOR_IDLE_THR | int | true | 0 | 1 | | FILTER_INIT_T | Time in ms to initialize estimator | int | 3000 | 0 | 100000 | -| FILTER_KP | estimator proportional gain - See estimator documentation | float | 0.5f | 0 | 10.0 | +| FILTER_KP_ACC | estimator proportional gain on accel-based error - See estimator documentation | float | 0.5f | 0 | 10.0 | | FILTER_KI | estimator integral gain - See estimator documentation | float | 0.01f | 0 | 1.0 | -| FILTER_KP_COR | estimator proportional gain on external attitude correction - See estimator documentation | float | 10.0f | 0 | 1.0 | +| FILTER_KP_EXT | estimator proportional gain on external attitude-based error - See estimator documentation | float | 1.5f | 0 | 10.0 | | FILTER_ACCMARGIN | allowable accel norm margin around 1g to determine if accel is usable | float | 0.1f | 0 | 1.0 | | FILTER_QUAD_INT | Perform a quadratic averaging of LPF gyro data prior to integration (adds ~20 us to estimation loop on F1 processors) | int | 1 | 0 | 1 | | FILTER_MAT_EXP | 1 - Use matrix exponential to improve gyro integration (adds ~90 us to estimation loop in F1 processors) 0 - use euler integration | int | 1 | 0 | 1 | @@ -184,18 +320,15 @@ This is a list of all ROSflight parameters, including their types, default value | GROUND_LEVEL | Altitude of ground level (m) | float | 1387.0f | -1000 | 10000 | | DIFF_PRESS_BIAS | Differential Pressure Bias (Pa) | float | 0.0f | -10 | 10 | | RC_TYPE | Type of RC input 0 - PPM, 1 - SBUS | int | 0 | 0 | 1 | -| BATT_VOLT_MULT | Battery monitor voltage multiplier | float | 0 | 0 | inf | -| BATT_CURR_MULT | Battery monitor current multiplier | float | 0 | 0 | inf | -| BATT_VOLT_ALPHA | Batter monitor voltage filter alpha. Values closer to 1 smooth the signal more. | float | 0.995 | 0 | 1 | -| BATT_CURR_ALPHA | Battery monitor current filter alpha. Values closer to 1 smooth the signal more.| float | 0.995 | 0 | 1 | | RC_X_CHN | RC input channel mapped to x-axis commands [0 - indexed] | int | 0 | 0 | 3 | | RC_Y_CHN | RC input channel mapped to y-axis commands [0 - indexed] | int | 1 | 0 | 3 | | RC_Z_CHN | RC input channel mapped to z-axis commands [0 - indexed] | int | 3 | 0 | 3 | | RC_F_CHN | RC input channel mapped to F-axis commands [0 - indexed] | int | 2 | 0 | 3 | +| RC_F_AXIS | NED axis that RC F-channel gets mapped to 0 - X, 1 - Y, 2 - Z | int | 2 | 0 | 2 | | RC_ATT_OVRD_CHN | RC switch mapped to attitude override [0 indexed, -1 to disable] | int | 4 | 4 | 7 | | RC_THR_OVRD_CHN | RC switch channel mapped to throttle override [0 indexed, -1 to disable] | int | 4 | 4 | 7 | -| RC_ATT_CTRL_CHN | RC switch channel mapped to attitude control type [0 indexed, -1 to disable] | int | -1 | 4 | 7 | -| ARM_CHANNEL | RC switch channel mapped to arming (only if PARAM_ARM_STICKS is false) [0 indexed, -1 to disable] | int | -1 | 4 | 7 | +| RC_ATT_CTRL_CHN | RC switch channel mapped to attitude control type [0 indexed, -1 to disable] | int | -1 | 4 | 7 | +| ARM_CHANNEL | RC switch channel mapped to arming (only if PARAM_ARM_STICKS is false) [0 indexed, -1 to disable] | int | -1 | 4 | 7 | | RC_NUM_CHN | number of RC input channels | int | 6 | 1 | 8 | | SWITCH_5_DIR | RC switch 5 toggle direction | int | 1 | -1 | 1 | | SWITCH_6_DIR | RC switch 6 toggle direction | int | 1 | -1 | 1 | @@ -204,13 +337,15 @@ This is a list of all ROSflight parameters, including their types, default value | RC_OVRD_DEV | RC stick deviation from center for override | float | 0.1 | 0.0 | 1.0 | | OVRD_LAG_TIME | RC stick deviation lag time before returning control (ms) | int | 1000 | 0 | 100000 | | MIN_THROTTLE | Take minimum throttle between RC and computer at all times | int | true | 0 | 1 | +| RC_MAX_THR | Maximum throttle command sent by full deflection of RC sticks, to maintain controllability during aggressive maneuvers | float | 0.7f | 0.0 | 1.0 | | RC_ATT_MODE | Attitude mode for RC sticks (0: rate, 1: angle). Overridden if RC_ATT_CTRL_CHN is set. | int | 1 | 0 | 1 | | RC_MAX_ROLL | Maximum roll angle command sent by full deflection of RC sticks | float | 0.786f | 0.0 | 3.14159 | | RC_MAX_PITCH | Maximum pitch angle command sent by full stick deflection of RC sticks | float | 0.786f | 0.0 | 3.14159 | | RC_MAX_ROLLRATE | Maximum roll rate command sent by full stick deflection of RC sticks | float | 3.14159f | 0.0 | 9.42477796077 | | RC_MAX_PITCHRATE | Maximum pitch command sent by full stick deflection of RC sticks | float | 3.14159f | 0.0 | 3.14159 | | RC_MAX_YAWRATE | Maximum pitch command sent by full stick deflection of RC sticks | float | 1.507f | 0.0 | 3.14159 | -| MIXER | Which mixer to choose - See Mixer documentation | int | Mixer::INVALID_MIXER | 0 | 10 | +| PRIMARY_MIXER | Which mixer to choose for primary mixer - See Mixer documentation | int | Mixer::INVALID_MIXER | 0 | 11 | +| SECONDARY_MIXER | Which mixer to choose for secondary mixer - See Mixer documentation | int | Mixer::INVALID_MIXER | 0 | 11 | | FIXED_WING | switches on pass-through commands for fixed-wing operation | int | false | 0 | 1 | | ELEVATOR_REV | reverses elevator servo output | int | 0 | 0 | 1 | | AIL_REV | reverses aileron servo output | int | 0 | 0 | 1 | @@ -219,4 +354,8 @@ This is a list of all ROSflight parameters, including their types, default value | FC_PITCH | pitch angle (deg) of flight controller wrt aircraft body | float | 0.0f | 0 | 360 | | FC_YAW | yaw angle (deg) of flight controller wrt aircraft body | float | 0.0f | 0 | 360 | | ARM_THRESHOLD | RC deviation from max/min in yaw and throttle for arming and disarming check (us) | float | 0.15 | 0 | 500 | +| BATT_VOLT_MULT | Multiplier for the voltage sensor | float | 0.0f | 0 | inf | +| BATT_CURR_MULT | Multiplier for the current sensor | float | 0.0f | 0 | inf | +| BATT_VOLT_ALPHA | Alpha value for the low pass filter on the reported battery voltage | float | 0.995f | 0 | 1 | +| BATT_CURR_ALPHA | Alpha value for the low pass filter on the reported battery current | float | 0.995f | 0 | 1 | | OFFBOARD_TIMEOUT | Timeout in milliseconds for offboard commands, after which RC override is activated | int | 100 | 0 | 100000 | diff --git a/latex-reports/mixer.tex b/latex-reports/mixer.tex index 22a9918..85d18b9 100644 --- a/latex-reports/mixer.tex +++ b/latex-reports/mixer.tex @@ -1,76 +1,18 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Short Sectioned Assignment -% LaTeX Template -% Version 1.0 (5/5/12) -% -% This template has been downloaded from: -% http://www.LaTeXTemplates.com -% -% Original author: -% Frits Wenneker (http://www.howtotex.com) -% -% License: -% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/) -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%---------------------------------------------------------------------------------------- -% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS -%---------------------------------------------------------------------------------------- - -\documentclass[paper=a4, fontsize=11pt]{scrartcl} % A4 paper and 11pt font size - -\usepackage[T1]{fontenc} % Use 8-bit encoding that has 256 glyphs -% \usepackage{fourier} % Use the Adobe Utopia font for the document - comment this line to return to the LaTeX default -\usepackage[english]{babel} % English language/hyphenation -\usepackage{amsmath,amsfonts,amsthm} % Math packages - -\usepackage{lipsum} % Used for inserting dummy 'Lorem ipsum' text into the template - -\usepackage{sectsty} % Allows customizing section commands -\allsectionsfont{\centering \normalfont\scshape} % Make all sections centered, the default font and small caps - -\usepackage{fancyhdr} % Custom headers and footers +\documentclass{article} +\usepackage[margin=1in]{geometry} % Required for inserting images \usepackage[margin=1in]{geometry} +\usepackage{amsmath} +\usepackage{blkarray} \usepackage{bm} -\usepackage{upgreek} \usepackage{tikz} -\usetikzlibrary{shapes, arrows} -\pagestyle{fancyplain} % Makes all pages in the document conform to the custom headers and footers -\fancyhead{} % No page header - if you want one, create it in the same way as the footers below -\fancyfoot[L]{} % Empty left footer -\fancyfoot[C]{} % Empty center footer -\fancyfoot[R]{\thepage} % Page numbering for right footer -\renewcommand{\headrulewidth}{0pt} % Remove header underlines -\renewcommand{\footrulewidth}{0pt} % Remove footer underlines -\setlength{\headheight}{13.6pt} % Customize the height of the header +\usetikzlibrary{arrows, shapes} -\setlength\parindent{0pt} % Removes all indentation from paragraphs - comment this line for an assignment with lots of text - -%---------------------------------------------------------------------------------------- -% TITLE SECTION -%---------------------------------------------------------------------------------------- - -\newcommand{\horrule}[1]{\rule{\linewidth}{#1}} % Create horizontal rule command with 1 argument of height - -\title{ -\normalfont \normalsize -\textsc{MAGICC Lab - Brigham Young University} \\ [25pt] % Your university, school and/or department name(s) -\horrule{0.5pt} \\[0.4cm] % Thin top horizontal rule -\huge Mixer \\ % The assignment title -\horrule{2pt} \\[0.5cm] % Thick bottom horizontal rule -} - -\author{James Jackson} % Your name - -\date{\normalsize\today} % Today's date or a custom date +\title{ROSflight Mixer Report} +\date{Last revision: \today} \begin{document} -\maketitle % Print the title - -%---------------------------------------------------------------------------------------- -% PROBLEM 1 -%---------------------------------------------------------------------------------------- +\maketitle +\tableofcontents \section{Introduction} @@ -78,9 +20,9 @@ \section{Introduction} In addition to the mixer, there is some saturation functionality baked into ROSflight. This functionality is insipired by that implemented in cleanflight, and serves to ensure that the MAV is always capable of responding to inputs, even during the most aggressive maneuvers. -The flow of information through the firmware can be visualized in Figure~\ref{fig:mixer_flow} +The flow of information through the mixer can be visualized in Figure~\ref{fig:mixer_flow}. -\begin{figure} +\begin{figure}[htbp] \centering \tikzstyle{int}=[draw, fill=white, minimum size=6em] \tikzstyle{init} = [pin edge={to-,thin,black}] @@ -88,48 +30,237 @@ \section{Introduction} \begin{tikzpicture}[node distance=4cm,auto,>=latex'] \node [int] (a) {mixer}; \node (b) [left of=a,node distance=4cm, coordinate] {a}; - \node [int] (c) [right of=a] {sat}; + \node [int] (c) [right of=a] {saturation}; \node [coordinate] (end) [right of=c, node distance=4cm]{}; - \path[->] (b) edge node {$\bm{\omega_c}, F$} (a); - \path[->] (a) edge node {$\hat{\tau}_1, \hat{\tau}_2 \ldots \hat{\tau}_n$} (c); - \draw[->] (c) edge node {$\tau_1, \tau_2 \ldots \tau_n$} (end) ; + \path[->] (b) edge node {$\bm{\omega_c}$} (a); + \path[->] (a) edge node {$\hat{\delta}_1, \hat{\delta}_2, \ldots \hat{\delta}_n$} (c); + \draw[->] (c) edge node {$\delta_1, \delta_2, \ldots \delta_n$} (end) ; \end{tikzpicture} \label{fig:mixer_flow} -\caption{The flow of information through the mixer and saturation function} +\caption{The flow of information through the mixer and saturation function, where $\bm{\omega_c}$ is the vector of desired commands.} \end{figure} \section{Mixer} -As mentioned before, the mixer is essentially a matrix multiplication. There are a number of mixers pre-programmed into ROSflight2, and they are published in [CITE]. They are designed to match the original mixers programmed into cleanflight, and they match the corresponding motor output diagrams, shown in Figure~\ref{fig:motor_layout}. First, an abstract command is calculated by the rate controller, or passed directly into the mixer (see controller paper), in the form of a four-tuple. $(F, x, y, z)$. In general, these are the actuatable degrees of freedom in the MAV, but specifically, in the case of a multirotor, this is interpreted as Force, Roll Torque, Pitch Torque, and Yaw Torque, $(F, \tau_x, \tau_y \tau_z)$, and in the case of a fixed-wing MAV, this is interpreted as throttle, aileron deflection, elevator deflection and rudder deflection $(T, \delta_a, \delta_e, \delta_r)$. The mixer then maps these commands to the 8 outputs available on the flight controller and executes the command. +As mentioned before, the mixer is essentially a matrix multiplication. +There are a number of mixers pre-programmed into ROSflight2, or a custom mixer can be used. +First, an abstract command is calculated by the rate controller, or passed directly into the mixer in the form of a six-tuple, $(F_x, F_y, F_z, Q_x, Q_y, Q_z)$, which represent the possible degrees of freedom of an arbitrary MAV. + +Note that the interpretation of these commands depends on the mixer used. +For example, in the case of a standard multirotor defined by the pre-programmed mixers, they are interpreted as x-force, y-force, z-force, roll torque, pitch torque, and yaw torque. +In the case of a standard fixed-wing MAV defined by the pre-programmed mixers, these are interpreted as throttle, nothing, nothing, aileron deflection, elevator deflection, and rudder deflection $(T, 0,0, \delta_a, \delta_e, \delta_r)$. -As an example, we will analyze the quadcopter-X mixing to show how it works. The rate controller, based on some higher-level input, calculates some command, $\bm{\omega}$. This is passed into the mixer, which is essentially the following 4x4 matrix: +The mixer then maps these commands to the 8 outputs available on the flight controller and executes the command. + +As an example, we will analyze the pre-programmed quadcopter-X mixing to show how it works. +The rate controller, based on some higher-level input, calculates some command, $\bm{\omega}$. +This is passed into the mixer, which in this case is the 4x4 matrix \begin{equation} - \begin{pmatrix} - 1 & 1 & 1 & 1 \\ - -1 &-1 & 1 & 1 \\ - -1 & 1 &-1 & 1 \\ - 1 &-1 &-1 & 1 \\ - \end{pmatrix} +\begin{blockarray}{ccccc} + & \delta_1 & \delta_2 & \delta_3 & \delta_4 \\ +\begin{block}{c(cccc)} + F_x & 0 & 0 & 0 & 0 \\ + F_y & 0 & 0 & 0 & 0 \\ + F_z & -0.25 & -0.25 & -0.25 & -0.25 \\ + Q_x & -0.7071 &-0.7071 & 0.7071 & 0.7071 \\ + Q_x & 0.7071 & -0.7071 & 0.7071 & -0.7071 \\ + Q_x & 1 &-1 & 1 & 1 \\ +\end{block} +\end{blockarray}, \end{equation} +where $\delta_i$ represents the $i$th output. -The remaining outputs are made available to modification by the GPIO inputs to the FC via MAVlink. It is assumed that PID gains in higher-level functions perform the scaling between the different channels to acheive the desired output. - -In addition, each mixer contains information about what kind of output each output channel is. For example, in the case of a fixed-wing. The output of the mixer for the first channel is attached to a motor while the other three are attached to servos. The output of a mixer to a servo must lie between -500 and 500, after which it is shifted up to the center of the servo output, or 1500$\upmu$s. Motor commands, on the other hand, are restricted to lie between 0 and 1000, and mapped to the full PWM range for standard ESC operation. +In this case, the first two rows corresponding to $F_x$ and $F_y$ are zeros, meaning that the MAV has no actuators in the $x$ or $y$ directions. +The third row has negative signs, meaning that the actuators point in the negative $z$ direction. +The torque values come from the geometry of a quadcopter-X. +See Section \ref{sec:derivation} for more details. +The remaining outputs are made available to modification by the GPIO inputs to the FC via MAVlink. +For the pre-programmed mixers, it is assumed that PID gains in higher-level functions perform the scaling between the different channels to acheive the desired output. -\begin{figure}[h] - \centering - \includegraphics[scale=0.3]{fig/motor_layout.jpg} - \label{fig:motor_layout} - \caption{The motor layout for the mixers} -\end{figure} +In addition, each mixer contains information about what kind of output each output channel is. +For example, in the case of a fixed-wing, the output of the mixer for the first channel is attached to a motor while the other three are attached to servos. +The output of a mixer to a servo must lie between -500 and 500, after which it is shifted up to the center of the servo output, or 1500$\upmu$s. +Motor commands, on the other hand, are restricted to lie between 0 and 1000, and mapped to the full PWM range for standard ESC operation. \section{Saturation} There are often agressive maneuvers which may cause multiple motor outputs to become saturated. This is of particular concern in multirotors, and can be illustrated in the example of the command of maximum roll while at full throttle in a quadcopter. Full throttle, with no other command, would normally cause all four motors to saturate at a maximum PWM command of 2000$\upmu$s. Mixing in a maximum roll command would cause two of the motors to reduce to 1500$\upmu$s, while the other two would go to 2500$\upmu$s. Because 2500$\upmu$s is beyond the maximum limit, the maximum roll command would actually be interpreted as a half-roll command as the difference between the motors on opposite sides of the MAV would be halved. To increase controllability in these sorts of situations, we take the motor control value from the mixer, before it is shifted up 1000$\upmu$s to the standard PWM range, and find the scaling factor which would reduce the maximum motor command to 1000$\upmu$s. We then apply this scaling factor to all other motors, and then shift them up to the standard PWM range of 1000$\upmu$s to 2000$\upmu$s. This does not completely solve the problem, because the maximum roll command is still reduced somewhat, but it trades off maximum thrust for some additional controllability. In the case of a simultaneous maximum roll and maximum throttle, two of the motors will receive a command of 2000$\upmu$s, while the other two will receive a command of 1333$\upmu$s, as opposed to the 1500$\upmu$s without the saturation, and maintains controllability even at high levels of throttle. - +\section{Mixer Equation Derivation}\label{sec:derivation} +There are two types of mixers available in ROSflight, ``canned"/pre-programmed mixers, and custom mixers. +Details of how to use each type of mixer can be found on the ROSflight website. +This section describes the derivation and assumptions of the mixer equations. +We first describe the derivation of a custom mixer for a generic multirotor. +We then describe the assumptions that were made to compute the ``canned" or pre-programmed mixers included with ROSflight. + +Note that many of the details of the mixer are more relevant to multirotor-type than fixedwing-type vehicles. + +\subsection{General Form} +As defined in \textit{Small Unmanned Aircraft: Theory and Practice} by Beard and McLain, the torque and thrust generated by a motor and propeller are +\[ \Vec{T}_{i} = C_T \frac{\rho D^4}{4 \pi^2} \Omega_i^2 \hat{e}_i \] +\[\begin{split} +\Vec{Q}_i & = \vec{r} \times \vec{T}_i + C_Q \frac{\rho D^5}{4 \pi^2} \Omega^2 d_i \hat{e}_i \\ + & = C_T \frac{\rho D^4}{4 \pi^2} \Omega_i^2 (\vec{r} \times \hat{e}_i) + C_Q \frac{\rho D^5}{4 \pi^2} \Omega_i^2 d_i \hat{e}_i, +\end{split}\] +where $\hat{e}_i$ is the unit vector pointed in the direction of the motor, $C_T$ and $C_Q$ are the torque and thrust coefficients associated with the propeller, $\rho$ is the air density, $D$ is the propeller diameter, $\vec{r}$ is the vector pointing from the center of rotation to the propeller plane, $d_i \in \{-1,1\}$ encodes the direction of rotation of a propeller, and $\Omega_i$ is the angular velocity of the propeller and motor. + +The desired forces and torques are transformed into desired angular velocities squared by the inverse of the mixing matrix $M$ according to +\[ +\begin{bmatrix} +\Vec{T}_d \\ \Vec{Q}_d \\ +\end{bmatrix} += +M +\begin{bmatrix} + \Omega_1^2 \\ + \Omega_2^2 \\ + \vdots \\ + \Omega_n^2 \\ +\end{bmatrix} += +\begin{bmatrix} + \Vec{T}_1 & \Vec{T}_2 & \hdots & \Vec{T}_n \\ + \Vec{Q}_1 & \Vec{Q}_2 & \hdots & \Vec{Q}_n \\ +\end{bmatrix} +\begin{bmatrix} + \Omega_1^2 \\ + \Omega_2^2 \\ + \vdots \\ + \Omega_n^2 \\ +\end{bmatrix} +\] +where $\Vec{T}_d$ and $\Vec{Q}_d$ are the desired thrust and torque. + +The $i^{\text{th}}$ column of M is then +\[ +\begin{bmatrix} +\Vec{T}_i \\ \Vec{Q}_i \\ +\end{bmatrix} += +C_T \frac{\rho D^4}{4 \pi^2} +\begin{bmatrix} + \hat{e}_i \\ + \vec{r} \times \hat{e}_i + \frac{C_Q D d_i}{C_T} \hat{e}_i \\ +\end{bmatrix} +\Omega_i^2. +\] +This is a general form, so it is valid for any motor configuration, and the desired angular speeds can be computed by inverting the mixing matrix $M$. + +If we know the motor parameters, we can compute the desired input voltage based on the desired angular velocities. +To do this, we set Equations 4.19 and 4.(1) from \textit{Small Unmanned Aircraft: Theory and Practice} equal to each other to get +\[ +V_{\text{in}} = \frac{R C_Q}{K_Q} \frac{\rho D^5 }{4 \pi^2} \Omega_i^2 + i_0 R + K_V \Omega_i. +\] +The throttle setting, $\delta_{t,i} \in [0,1]$ can then be calculated using $V_{\text{in}} = \delta_{t,i} V_{\text{max}}$. +This throttle setting is the PWM setting that the mixer writes to the motors, assuming that output voltage is scaled linearly to the PWM duty cycle setting. + +\subsection{Simplifications} +There are some simplifications we can make in order to generate mixing matrices that do not depend on the motor and propeller parameters. + +\noindent +\textbf{Assumption 1:} All motors and propellers are the same (i.e. have the same coefficients). + +\noindent +\textbf{Assumption 2:} $\hat{e}_i = -\hat{k} = \begin{bmatrix} + 0 \\ 0 \\ -1 +\end{bmatrix}$, +meaning that the motors are all oriented in the $-z$ direction (i.e. straight up). + +\vspace{10pt} +Then, +\[ +\vec{r} \times \hat{e}_i += +\begin{bmatrix} + r_y e_z - r_z e_y \\ + r_z e_x - r_x e_z \\ + r_x e_y - r_y e_x \\ +\end{bmatrix} += +\begin{bmatrix} + -r_y \\ + r_x \\ + 0 \\ +\end{bmatrix} +\] +and +\[ +c_1 +\begin{bmatrix} + \Vec{T}_i \\ \Vec{Q}_i \\ +\end{bmatrix} += +\begin{bmatrix} + 0 \\ + 0 \\ + 1 \\ + -r_y \\ + r_x \\ + \frac{C_Q D}{C_T} d_i \\ +\end{bmatrix} +\Omega_i^2, +\] +where $c_1 = \frac{4 \pi^2}{C_T \rho D^4}$. + +\vspace{10pt} +\noindent +\textbf{Assumption 3:} Each desired torque value is computed independently (i.e. separate gains) than the other desired forces and torques. +Additionally, $\ell=1$, so that $r_y = \text{sin}\theta$ and $r_x = \text{cos}\theta$. + +\vspace{10pt} +\noindent +Then the constant terms in those equations can be factored out of the equations and subsumed into the gains and we get +\[ +\vec{c}_1^T +\begin{bmatrix} + \Vec{T}_i \\ \Vec{Q}_i \\ +\end{bmatrix} += +\begin{bmatrix} + 0 \\ + 0 \\ + 1 \\ + -r_y \\ + r_x \\ + d_i \\ +\end{bmatrix} +\Omega_i^2, +\] +which is intuitive, since it comes straight from the geometry. +Note that $\vec{c}_1$ becomes a vector since the rows have different constants associated with them. + +\vspace{10pt} +\noindent +\textbf{Assumption 4:} $V_{\text{in}} \approx \frac{R \rho D^5 C_Q}{4 \pi^2 K_Q} \Omega_i^2$, meaning that the first term in the $V_\text{in}$ equation dominates. + +\vspace{10pt} +\noindent +Then, since $V_{\text{in}} = \delta_{t,i} V_{\text{max}}$ we have +\[ +\vec{c}^T_2 +\begin{bmatrix} + \Vec{T}_i \\ \Vec{Q}_i \\ +\end{bmatrix} += +\begin{bmatrix} + 0 \\ + 0 \\ + 1 \\ + -r_y \\ + r_x \\ + d_i \\ +\end{bmatrix} +\delta_{t,i}, +\] +where $\vec{c}_2 = \frac{R \rho D^5 C_Q }{4 \pi^2 K_Q V_{\text{max}}} \vec{c}_1$. + +Since the desired forces and torques come from a controller, (specifically a PID controller in the firmware), the $\vec{c}_2$ constants could be wrapped up in the gains associated with each controller, and the columns of the mixing matrix become the right-hand sided of the above equation. + +With this formulation, we can define canned mixers that don't require knowledge of the motor and propeller parameters. +This formulation makes a trade-off between the accuracy of the commands (see Assumption 4) and the simplicity and intuitiveness for the user. \end{document} +