When to use Laplace Transform vs. Z-Transform in robotics

 I had to learn Laplace transform and Z-Transform during my engineering study. After many years I have been revisiting these mathematical tools. I wondered where these could be applied in robotics with Arduino or similar microcontrollers like ESP32 boards. This note is about this, where and when to use Laplace and Z transforms.

So first of all, Laplace transform is for continuous systems (analog systems) and Z-transform is for discrete systems (digital systems), meaning that Laplace is used when modeling physical systems like DC motors or mechanical arms using differential equations, while Z-transform is applied when implementing these models in microcontrollers such as Arduino using sampled or digitized signals. For example, when controlling the speed of a DC motor, you first model the motor using Laplace transform to get a transfer function like ω(s)V(s)=K(Js+b)(Ls+R)+K2\frac{\omega(s)}{V(s)} = \frac{K}{(Js + b)(Ls + R) + K^2}, where ω(s)\omega(s) is motor speed and V(s)V(s) is input voltage. Then, you design a continuous-time PID controller in Laplace domain to achieve desired performance (such as faster response or reduced overshoot), convert the controller into a discrete-time form using the Z-transform or Tustin approximation, and finally implement the difference equations in Arduino code that reads motor speed using an encoder and adjusts the PWM signal accordingly to control the motor in real time.

Step 1: Model the DC Motor in Laplace Domain

Use the physical parameters of a DC motor to derive the transfer function G(s):

🧮 DC Motor Model

G(s)=ω(s)V(s)=K(Js+b)(Ls+R)+K2G(s) = \frac{\omega(s)}{V(s)} = \frac{K}{(Js + b)(Ls + R) + K^2}

Where:

  • J: moment of inertia (kg·m²)

  • b: damping coefficient (N·m·s)

  • R: armature resistance (Ω)

  • L: inductance (H)

  • K: motor torque/back-emf constant

You can simplify this into a first-order system for simulation:

G(s)=Kτs+1G(s) = \frac{K}{\tau s + 1}

⚠️ Note: G(s) is fixed, based on the physical motor.

Step 2: Design the Controller C(s)

Design a PID controller in the Laplace domain to improve motor response:

C(s)=Kp+Kis+KdsC(s) = K_p + \frac{K_i}{s} + K_d s

Tune Kp,Ki,KdK_p, K_i, K_d using:

  • Ziegler–Nichols method

  • Trial-and-error

  • Simulation feedback

🎯 The controller C(s) is designed based on the motor model G(s).

Step 3: Discretize the Controller to C(z)

To implement the PID controller on Arduino (discrete system), convert C(s) to C(z) using Z-transform.

Use Tustin (bilinear) approximation:

  • s2T1z11+z1s \approx \frac{2}{T} \cdot \frac{1 - z^{-1}}{1 + z^{-1}}

The PID controller in discrete form becomes:

u[n]=u[n1]+Kp(e[n]e[n1])+KiTe[n]+KdT(e[n]2e[n1]+e[n2])u[n] = u[n-1] + K_p(e[n] - e[n-1]) + K_i T e[n] + \frac{K_d}{T}(e[n] - 2e[n-1] + e[n-2])

Where:

  • u[n]: PWM output

  • e[n]: current error (desired - actual speed)

  • T: sampling time (e.g., 0.1s)

Step 4: Arduino PID Implementation (Code)


// PID constants
float Kp = 1.2, Ki = 0.5, Kd = 0.05;
float T = 0.1; // 100 ms

float e[3] = {0};
float u = 0;

int setSpeed = 512; // Mid-scale for potentiometer range 0-1023
int motorPin = 9;

unsigned long lastTime = 0;

void setup() {
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (millis() - lastTime >= T * 1000) {
    lastTime = millis();

    e[2] = e[1];
    e[1] = e[0];

    int feedback = analogRead(A0);
    e[0] = setSpeed - feedback;

    float du = Kp * (e[0] - e[1]) + Ki * T * e[0] + Kd / T * (e[0] - 2 * e[1] + e[2]);
    u += du;

    u = constrain(u, 0, 255);
    analogWrite(motorPin, (int)u);

    Serial.print("Speed: ");
    Serial.println(feedback);
  }
}


This Arduino code implements a discrete PID (Proportional-Integral-Derivative) controller to regulate the speed of a DC motor. It reads the actual speed (or a proxy like a potentiometer or analog sensor) from analog pin A0 every 100 milliseconds, compares it with a setpoint (setSpeed = 512), and calculates the error. Using PID logic, it computes the necessary adjustment (du) and updates the PWM control signal (u) sent to the motor via pin 9. The PWM value is constrained between 0 and 255 to control the motor speed. The feedback value is also printed to the Serial Monitor for observation and debugging.

This code does not use any arduino PID library like PID_v1.h. This pid code uses manual discrete PID logic, giving you complete control over how errors are handled, how tuning is applied, and how each PID component behaves. This makes it more flexible and educational, but also prone to bugs and harder to maintain if your project grows.


Post a Comment

Previous Post Next Post