# PT1 plant model

• IP-Core to model a PT1 plant

$G(s)=\frac{K}{Ts +1}$

With the gain $$K$$ and time constant T.

• Intended for HIL/SIL/xIL on the UltraZohm

• PT1 is implemented in discrete time by using zero order hold transformation

• Sample time of the integrator is $$T_s=\frac{1}{1\,MHz}$$

• IP-Core clock frequency must be $$f_{clk}=100\,MHz$$!

• IP-Core has single precision AXI ports

• All calculations in the IP-Core are done in double precision!

• Rationale: the machine epsilon for single precision is approximately $$\epsilon=6e-08$$. The time discrete integrator multiplies the input with $$\frac{1}{T_s}$$, resulting in small numbers. This results in noticable rounding errors for the integration compared to double precision. This effect als consistent between the IP-Core and Simulink, thus double precision is used in the IP-Core. AXI is 32-bit by default, thus the input and output values are converted to single precision.

## IP-Core Hardware

• The module takes all inputs and converts them from single precision to double precision.

• The output is converted from double precision to single precision (using rounding to nearest value in both cases).

• All input values are adjustable at run-time

• The sample time is fixed!

• The IP-Core uses Native Floating Point of the HDL-Coder

• The time constant is written as its reciprocal to the AXI register to make the calculations on hardware simple (handled by the driver!)

• The IP-Core uses an oversampling factor of 100

## Example usage

• Source IPCORE_CLK with a $$100\,MHz$$ clock!

• Connect other ports accordingly

• Build bitstream, export .xsa, update vitis platform

### Vitis

• In a c-file that has xparameters.h included

• Initialize the instance and configure it

struct uz_plantPT1_config_t config={
.ip_core_frequency_Hz=100000000,
.gain=1.0f,
.time_constant=1.0f
};
uz_plantPT1_t* pt1=uz_plantPT1_init(config);
uz_plantPT1_set_input(pt1,0.0f);

• Write the input and read the output of the block in the isr.c

• Add a PI controller to control the PT1 (for example)

static float error_sum=0;
float error=input-output;
error_sum+=error;
float K_p=0.3f;
float K_i=1.3f;
float pi_output=K_p*error+K_i*(1.0f/20000.0f)*error_sum; // 20000.0f is the sample rate of the ISR in this example
uz_plantPT1_set_input(pt1,pi_output);


## Driver reference

typedef struct uz_plantPT1_t uz_plantPT1_t

Object definition of the plant model PT1 IP-Core.

struct uz_plantPT1_config_t

Configuration struct for plant PT1 IP-Core.

Public Members

uint32_t ip_core_frequency_Hz

Clock frequency of IP-Core

float gain

Gain of PT1

float time_constant

time constant of the PT1

uz_plantPT1_t *uz_plantPT1_init(struct uz_plantPT1_config_t config)

Initialize an instance of the driver.

Parameters
• config – Configuration struct

Returns

uz_plantPT1_t* Pointer to initialized instance of driver

void uz_plantPT1_reset_integrator(uz_plantPT1_t *self)

Resets the integrator of the PT1 once.

Parameters
• self – Pointer to driver instance that is reset

void uz_plantPT1_set_input(uz_plantPT1_t *self, float input_value)

Set the input value u(k) of the PT1.

Parameters
• self – Pointer to driver instance

• input_value

void uz_plantPT1_set_gain(uz_plantPT1_t *self, float gain)

Set the gain of the PT1.

Parameters
• self – Pointer to driver instance

• gain

void uz_plantPT1_set_time_constant(uz_plantPT1_t *self, float time_constant)

Set the time constant of the PT1.

Parameters
• self – Pointer to driver instance

• time_constant