ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
3 мая
1357412 Топик полностью
framer (03.10.2023 14:39, просмотров: 205) ответил framer на В умных книжках пишут. Чтобы получить ответ системы надо сделать свертку входного сигнала и весовой функции. Вот весовая функция апериодического звена
Вот реалный пример как это сделать на Ц. 

Причесал свертку и взял ПИД из ссылки.

Это модель

#ifndef MODEL_H_

#define MODEL_H_

#include <math.h>

struct convolve_params{

float* h;

size_t size;

float* input;

float* output;

};

void set_aperiodic_weight(float T, float sample_period, size_t size, convolve_params* cpar);

void set_square_weight(float ampl, size_t size, convolve_params* cpar);

float convolve(float x, convolve_params* cpar);

#endif // MODEL_H_


#include "model.h"


void set_aperiodic_weight(float T, float sample_period, size_t size, convolve_params* cpar) {

cpar->h = (float*)malloc(size*sizeof(float));

cpar->input = (float*)malloc(size*sizeof(float));

cpar->output = (float*)malloc(size*sizeof(float));

cpar->size = size;

float t = 0.0;

for (size_t i = 0;i<size; i++) {

cpar->h[i] = 5/T *(exp(-t/T));

cpar->input[i] = 0.0;

t += sample_period;

}

}


void set_square_weight(float ampl, size_t size, convolve_params* cpar) {

cpar->h = (float*)malloc(size*sizeof(float));

cpar->input = (float*)malloc(size*sizeof(float));

cpar->output = (float*)malloc(size*sizeof(float));

cpar->size = size;

for (size_t i = 0;i<size; i++) {

cpar->h[i] = ampl;

cpar->input[i] = 0.0;

}

}


float convolve(float x, convolve_params* cpar) {

for (size_t i = cpar->size-1; i>0; i--){

cpar->input[i] = cpar->input[i-1];

}

cpar->input[0] = x;

float integral = 0;

for (size_t i = 0; i<cpar->size; i++){

float step = cpar->h[i]*cpar->input[i];

cpar->output[i] = integral + step;

integral += step;

}

return (cpar->output[cpar->size-1] / cpar->size);

}


Модель можно проверить на ответ


static void get_responce(convolve_params* p) {

for (size_t i=0;i<20;i++) {

std::cout << convolve(0, p) << std::endl;

}

for (size_t i=0;i<50;i++) {

std::cout << convolve(1, p) << std::endl;

}

for (size_t i=0;i<100;i++) {

std::cout << convolve(0, p) << std::endl;

}

}


....


convolve_params p;

set_aperiodic_weight(1, 0.1, 50, &p);

//set_square_weight(1, 50, &p);

get_responce(&p);



А вот ПИД + модель. Параметры од балды но тут хотел показать как работает.

struct pid_params{

float ITerm, lastInput;

float kp, ki, kd;

float outMin, outMax;

};

float PIDCompute(float Input, float Setpoint, pid_params* pidp )

{

float Output;

/*Compute all the working error variables*/

float error = Setpoint - Input;

pidp->ITerm+= (pidp->ki * error);

if(pidp->ITerm> pidp->outMax) pidp->ITerm= pidp->outMax;

else if(pidp->ITerm< pidp->outMin) pidp->ITerm= pidp->outMin;

float dInput = (Input - pidp->lastInput);

/*Compute PID Output*/

Output = pidp->kp * error + pidp->ITerm- pidp->kd * dInput;

if(Output> pidp->outMax) Output = pidp->outMax;

else if(Output < pidp->outMin) Output = pidp->outMin;

/*Remember some variables for next time*/

pidp->lastInput = Input;

return Output;

}

int main(int argc, char *argv[])

{

convolve_params p;

pid_params pidp;

pidp.ITerm = 0;

pidp.lastInput = 0;

pidp.kp = 0.1;

pidp.ki = 3;

pidp.kd = 0;

pidp.outMin = 0;

pidp.outMax = 10.0;

set_aperiodic_weight(1, 0.1, 50, &p);


float responce = 0;

float pid_out = 0;

for (size_t i =0 ; i < 1000; i++) {

responce = convolve(pid_out, &p);

pid_out = PIDCompute(responce,0.5,&pidp);

std::cout << responce << "," << pid_out << std::endl;

}

return 0;

}





Так что без теории никак.