Signal processing

While thinking about ways to implement multiple sensor support – for several GPS or gyroscopes – I realized that an UAV can be modeled as a signal processing device.

It can be split like this:

  • sources – like the MPU9250 which generates 4 signal streams: acceleration, angular velocity, magnetic field and temperature, the SRF02 sonar which generates a stream of distances
  • streams – like the acceleration from the imu, or the location stream from the GPS. Each stream has a sample rate
  • sink – like the pigpio PWM. Sinks accept streams of a certain sample rate only
  • and processors – like low pass filters (LPF) or the PIDs, or the AHRS. Processors don’t have an inherent sample rate. They adopt the rate of the input usually.

All of these are implemented as nodes with several inputs and outputs. All nodes are added to the HAL layer and both their properties and connections are configured from a json file.

The important aspect is that – like all signal processing – signal rate is very important and has to be properly matched between nodes to satisfy the nyquist frequency. For example the PWM has a max sample rate of 490Hz so any signal higher than ~240Hz will be seen as noise. Higher frequency signals have to be resampled and low-pass-filtered before fed in the PWM node.

I started implementation last week and – after many rewrites – I have a model that ‘feels right’.

Here are some drawings:


Here the MPU9250 node exposes 4 sub-nodes (not shown) – an accelerometer, a gyroscope, a magnetometer and a thermometer. Each of these outputs a stream: acceleration stream, angular velocity, magnetic field and temperature.

The frequency of these streams is determined by the sensor. Acceleration and Angular Velocity are at 1Khz while magnetic field is at 100Hz. Temperature (not shown in the pic) is at 10Hz.

The Magnetic Field stream is fed into a Resampler node that takes it from 100Hz to 1000Hz, ready to be fed into the AHRS procesor node. The reason for this is that upsampling the stream needs a low-pass flter to avoid parasitic frequencies. A sample rate of 100Hz can carry at most a 50Hz signal so when going to 1000Hz sample rate this max frequency has to be maintained. Simply cloning each sample 10 times is not enough as this adds a lot of high frequency harmonics.

So now all signals at 1Khz sample rate are fed into the AHRS which outputs a Reference Frame stream, also at 1Khz. This reference frame represents the rotation of the UAV relative to earths frame of reference.

Right now I have a complimentary filter for the AHRS node but in the ear future I will write an extended kalman filter (EKF) for it – as soon as this tutorial is complete.


This diagram uses the AHRS output – the reference frame stream – plus the acceleration stream again to output 2 new streams – gravity vector and linear acceleration. These 2 streams will be further used for dead reckoning and stability pids.


Here I have the basic rate PIDs diagram. The angular velocity stream is first resampled from 1KHz to 50Hz (the pic says LPF but it’s actually a resampler node). The reason for this is that the usable bandwidth of the quadcopter is ~20-30Hz. Anything higher than this is noise.

The stream is further passed to the Rate PID processor node which outputs a torque stream (also at 50Hz). Torque is converted to thrust using a model of the motors+propellers (configurable of course), which is fed to the motor mixer and then in the PWM sink.

The advantage of this system is that new processors can be easily added to accommodate new hardware. For example if I want to use 2 GPS sensors I will add a redundancy processor that takes 2 location streams and outputs the healthiest one. Or I can merge them together to get better accuracy – while the rest of the nodes don’t even know nor care about this.

Basically I have minimal coupling between the elements of the system which talk through very well defined (and type safe) interfaces.

The ground station is also simplified. It can enumerate ll the nodes, read their configuration as a json value, change it and push it back to the nodes. Changing a filter cutoff will become trivial.

So far I still working to match the old functionality but in 1-2 weeks I believe this system will be ready for a test.

5 thoughts on “Signal processing

  1. This is a really great approach to the flight control system. And it seems you got something robust here. I do have some questions though:

    – “For example the PWM has a max sample rate of 490Hz so any signal higher than ~240Hz will be seen as noise.” What is this PWM sample rate? Is it the “standard” coding used for RC servo and also the ESC?

    – I don’t get why the “usage bandwidth” is only 30Hz. What is it?

    – Shouldn’t the sink frequency drives all the other ones? If your PWM can only process 500 samples/s, is it necessary to process the AHRS at 1kHz? You could down-sample everything at the sources output so that you don’t process useless data… And the next article says you down sample the sensors to 50Hz before feeding the pilot 😉

    – And finally what happens if some stream goes down? Say the magnetic field is missing, for any reason (what happens in hardware stays in hardware). How do you drive the process nodes? They should not stop processing because of a missing stream, and you would also enter a panic mode (return to home if comm is lost, emergency landing if some important sensor is dead)… This is maybe not the goal for now, but should definitively help design the system.

    Good work! Again I find the signal processing vision very interesting 🙂

    1. Hi cyprien,

      Servos and ESCs are usually driven by a 50Hz ‘special’ PWM but this can be increased to about 490Hz. Some ESC firmwares – like BlHeli – can also use 1, 2, 4, 8 Khz pure PWM signals.
      For 490Hz the max usable signal frequency (or rate of change of input) is ~245Hz which is the nyquist frequency. Above this the signal looses its shape and is seen as noise because of aliasing.

      The control bandwidth of a quadcopter is limited by the angular inertia of the motors, props and frame itself. Inputs that are faster than this bandwidth are attenuated too much to make any observable difference. You can imagine a quad changing its pitch 30 times per second – the heavier it is the more inertia it has and faster changes become more and more difficult. Also, very sudden changes require more bandwidth and this is modeled by a rectangular signal – the sharper the edge of the signal the higher frequency harmonics it needs.
      If you go above the bandwidth you don’t get useful responses anymore.
      For a quad of average size, the max frequency of the signal + all its harmonics (that determine the shape of the input signal – sinusoidal or square) fit in 30Hz. Maybe 50, maybe 20 but around this number. I’ll have to research this more.

      The sinks do require that their sample rate is respected. However other nodes require higher sample rates – like the AHRS node which does angular velocity integration. The higher sample rate for AHRS the more accurate the integration is. The pilot – on the other hand doesn’t need this high sample rate. Right now the 1K sample rate is kept until after the AHRS and then resampled before entering the pilot.

      Every stream has a is_healthy flag and a sample_idx that is incremented for new data. The healthy flag is viral – if any one of the 3 AHRS input streams goes down, its output also becomes unhealthy. In the end the pilot will have to deal with this depending on the stream.
      If the Location stream is down, the quad can still land and fly ok. If the angular velocity, acceleration or magnetic field go down then there’s little the pilot can do. Maybe turn off the motors to minimize possible damage.

      Thanks 🙂

      1. Hi, after soldering MPU9250, did you experience any difficulty to communicate with the IMU ?
        My soldering seems to be good, but the IMU is not responding…

          1. I found the issue: the pin ADo/SD0 for the I2C address selection must be to GND or VCC. If this pin is not connected, the MPU doesn’t work at all.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s