Quadcopter modelling in MATLAB and Simulink

I finished Dynamics and Control with 99%. In its labs I modelled a 6.3 kg quadcopter’s vertical motion from first principles, built the model in Simulink, linearised it about hover and analysed its responses in MATLAB, then measured the kinematics of a six-axis robot arm, a four-legged robot and a drone.

Year
Year 2
Module
Dynamics and Control ME547
Period
Autumn 2025 – Jan 2026
Team
Individual
My Simulink model of the quadcopter’s vertical acceleration, a = g − b(Ω₁² + Ω₂² + Ω₃² + Ω₄²)/M.

99%

Module mark

−1/(6.3 s²)

Transfer function of my linearised hover model

0.044–0.280 rad/s

Robot-arm base joint speeds, at settings of 10–70%

1.01 m/s

Measured walking speed of the four-legged robot

The labs

Three labs took one system from first principles to simulation, then moved to measuring real robots. I wrote up each one myself; the measurements in the third were taken with my lab group. MATLAB and Simulink ran through all of it.

Lab 1: modelling a quadcopter’s vertical motion

I drew the free-body diagram with the four rotor thrusts and the weight. Each rotor’s thrust is T = bΩ², so the total is T = b(Ω₁² + Ω₂² + Ω₃² + Ω₄²). Taking z as positive downwards, Newton’s second law gives a = g − T/M, with M = 6.3 kg.

My free-body diagram and rotor thrust model, T = bΩ².

I built the model in Simulink: the four motor speeds are squared and summed, multiplied by the thrust coefficient b = 2.02 × 10⁻⁷ N/rpm² and by 1/M, and subtracted from g to give the vertical acceleration, so any combination of motor speeds can be fed in and its effect read off the scope.

Lab 2: the hover model in MATLAB

Near hover the thrust balances the weight, so I wrote the total thrust as T = mg + u, where u is the control input. That leaves m·z̈ = −u, and with zero initial conditions the Laplace transform gives the transfer function from thrust input to altitude, G(s) = −1/(6.3 s²): a double integrator. I set it up in MATLAB and simulated its step, impulse and ramp responses:

m = 6.3;
G = tf(-1/m, [1 0 0]);
step(G); impulse(G);
t = 0:0.01:10; u = t; lsim(G, u, t);
Step
Altitude follows a parabola, z = −t²/(2m).
Impulse
A single kick gives a constant-velocity drift, z = −t/m.
Ramp
Altitude grows with t³.

I checked each plot against its closed-form solution, and they match exactly. Because the open-loop system is a double integrator, it never settles: the steady-state error is infinite and the rise and settling times are undefined. That’s the case for feedback control: without it, a quadcopter can’t hold an altitude. Negative z is upwards.

Step response of the hover model in MATLAB: altitude diverges as a parabola.
Impulse response: a single kick gives a constant-velocity drift.

Lab 3: kinematics of robot systems

Six-axis robot arm
I sketched the arm with joints A1–A6 and their link lengths, recorded the reference angles, and classified each joint’s motion. I timed the base joint through 90° at speed settings from 10% to 70%: 35.7 s down to 5.6 s, or 0.044 to 0.280 rad/s. The speed isn’t proportional to the setting: 70% ran 6.4 times faster than 10%, not 7 times. I then moved single and double links through set angles and compared the measured tip positions with forward-kinematics calculations.
Four-legged robot
I classified the motion of its body, legs and feet, and timed it walking 9.92 m out and back in manual mode: a mean of 9.78 s over three runs, or 1.01 m/s.
Drone
It climbed to 1.79 m and returned in 15.8 s, an average speed of 0.23 m/s, and flew a 3.48 m straight diagonal path in 14.8 s, 0.24 m/s.
My sketch of the six-axis arm with joints A1–A6 and link lengths in mm.
The base joint timed through 90° at speed settings of 10–70%.

What I took from it

Building the model by hand first, then in Simulink, then as a transfer function in MATLAB, and checking each step against the last, is how I now approach any dynamic system. The labs also showed where the next steps lie:

  • Close the loop. The open-loop model shows why a quadcopter needs feedback. The next step is a PD or PID altitude controller, tuned with root locus or Bode plots and checked with its closed-loop step response.
  • Add the rotational dynamics. The rotor spin directions set a yaw torque, so a full model needs roll, pitch and yaw as well as vertical motion.
  • Simulate over realistic times. A 10 s window, as I used for the ramp, suits a drone better than MATLAB’s automatic 900 s span. I’d also keep the motor speeds in rad/s throughout.
  • Calibrate before comparing. The 25–64% differences between measured and calculated arm positions came mainly from the robot’s joint-angle readout using a different convention from my trigonometry, so I’d calibrate the angle convention first and repeat each timing to state the uncertainty.

Project details

Module
Dynamics and Control ME547
Year
Year 2
Period
Autumn 2025 – Jan 2026
Team
Individual
Skills
MATLAB, Simulink
Disciplines
Dynamics & control
Status
Complete