Sistema de control difuso de velocidad del carro
El algoritmo de control de velocidad del coche inteligente adopta un control difuso.
La mayoría de los algoritmos de control de la competencia utilizan algoritmos de control PID. PID puede responder rápidamente, pero no es suficiente tener la función correspondiente de controlar rápidamente la velocidad del automóvil. de manera diferente según las condiciones reales de la pista. Para lograr el objetivo de pasar por diferentes condiciones de la carretera lo más rápido posible, se utiliza el razonamiento difuso para lograr el control de velocidad del automóvil.
Haga clic para ingresar la descripción de la imagen
1. Variable difusa
En el control difuso, los tamaños de las variables de entrada y salida se describen en lenguaje. Los siete valores de idioma generalmente seleccionados son {negativo grande, negativo medio, negativo pequeño, cero, positivo pequeño, positivo mediano, positivo grande}, es decir, {NB, NM, NS, O, PS, PM, PB}.
La desviación e formada por la dirección de desplazamiento actual del automóvil y la dirección de la pista y su tasa de cambio ec se utilizan como entrada del controlador difuso, y la velocidad objetivo del automóvil es la salida del controlador difuso. Suponga que la ambigüedad del valor de desviación es E, la ambigüedad de la tasa de cambio de desviación es EC y U es la velocidad objetivo. Para hacer que el cambio de velocidad sea más delicado y suave, los valores teóricos básicos del valor de desviación E, la tasa de cambio de desviación EC y la variable de control u se establecen en y se dividen en 13 niveles, a saber, {-6, -5, -4, -3, - 2, -1, 0, 1, 2, 3, 4, 5, 6}.
E, EC y U utilizan funciones de membresía triangular para la difuminación
Haga clic para ingresar la descripción de la imagen
/**
* Coordenadas de columna: NB, NM, NS, O, PS, PM, PB
* Coordenadas horizontales: -6,-5,-4,-3,-2,-1,0,1, 2,3,4,5,6
*@param establece la función de membresía de entrada y salida y ajusta el rango de ajuste difuso
*//****** ****** ********************************** Función de membresía incorrecta ******* **************** ********************** **/float Input1_Terms_Membership[7][13] ={ 1 ,0.15,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0 ,0,0,0,0,0 ,0,1,0.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0};/********* ********************************** error cambio función de afiliación de tarifas *************** *************************/float Input2_Terms_Membership[7][13 ] ={ 1,0.15,0,0,0,0,0, 0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0, ******* ***********/float Output_Terms_Membership[7][ 13] ={ 1,0.15,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0.2 ,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,2 ,1};123456789101112131415161718192021222324252627282930313233343536
2. >Establezca la tabla de reglas de control difuso correspondiente para las cantidades difusas EC, E y U
Haga clic en la imagen para ingresar una descripción
/**
* El eje vertical es E (error), el eje horizontal es EC (error_delta) y el valor es NB (0), NM (1), NS
(2), Z(3), PS(4), PM(5), PB(6) La velocidad de las siete marchas es de pequeña a grande y luego de grande a pequeña
* Coordenadas de columna : E (NB,NM,NS,O,PS PM,PB)
* Abscisa: EC (NB,NM,NS,O,PS,PM,PB)
* Valor: U (1:NB:2,NM,3:NS,4:O,5:PS,6:PM,7:
* @parameter se utiliza para ajustar la regla de control difuso de velocidad tabla de tendencias de cambio
*/int Rule[7][7] ={ 1,1,2,2,6,7,7,
1,1,2,2 ,6 ,6,6,
1,2,3,4,5,6,6,6,
1,3,4,4,4,5,7 ,
2,2,3,4,5,6,7,
2,2,2,2,6,7,7
1 ,1 ,2,2,6,7,7};//Parámetro de depuración 12345678910111213141516
Relación difusa implícita en la base de reglas:
La operación difusa × significa "tomar el mínimo valor".
Haga clic para ingresar la descripción de la imagen
Después de calcular la relación difusa R implícita en la regla difusa, seleccione el valor difuso, recorra todos los dominios de E y EC, y calcule el valor de salida difuso:
Entre ellos, o representa la síntesis de matrices difusas, que es similar a la operación de multiplicación de matrices ordinarias. La operación de multiplicación se reemplaza por "tomar el valor más pequeño" y la suma. la operación se cambia a "tomar el valor mayor".
Haga clic para ingresar la descripción de la imagen.
Durante el proceso transversal, se utiliza el método de promedio ponderado para desdibujar los valores de salida difusos. correspondientes a todas las teorías de E y EC una por una para obtener la tabla final de búsqueda de controladores difusos.
flotante ?R[169][13] = { 0 }; flotante R1[13][13] = { 0 }; flotante AdBd1[13][13] = { 0 }; 169] = { 0 }; flotante AdBd2[169] = { 0 }; flotante R3[169][13] = { 0 }; flotante R3[169][13] = { 0 }; {0}; Float Fuzzy_table [13] [13] = {0}; Velocidad de flotación [13] = {200,220,230,240,270,300,270,250,230,200}; En la implementación del dominio de parámetros del proceso de fuzzificación, el valor del idioma correspondiente al grado máximo de pertenencia de diferentes valores
*/int ?E_MAX(int e){
int i = 0, max = 0;
for (i = 0; i < 7; i++)
if (Input1_Terms_Membership[i][e] > Input1_Terms_Membership[max] [e ])
max = i;
return max;}int ?EC_ MAX(int ex){
int i = 0, max = 0 ;
for (i = 0; i < 7; i++)
if (Input2_Terms_Membership[i][ex] > Input1_Terms_Membership[max][ ex])
max = i;
return max;}void calcular(){
/******************** ** ******************* Calcule las reglas del conjunto de conexiones de todas las relaciones difusas de reglas *************** ****** * *******************/
int i = 0, j = 0, k = 0
int Input1_value_index; = 0, Input2_value_index = 0;
// Reglas de cálculo (inicialización), calcula Rij y toma todos los conjuntos de R como conjuntos de conexiones, R=(EXEC)XU
for ( Entrada1_Terms_Index = 0 ; Entrada1_Terms_Index < 7; Entrada1_Terms_Index++)
para (Input2_Terms_Index = 0; Entrada2_Terms_Index < 7; Entrada2_Terms_Index++)
{
// Idioma para E y los valores EC y sus resultados se combinan en pares para calcular la Regla
Output_Terms_Index = Rule[Input1_Terms_ Index][Input2_Terms_Index] - 1;
k = 0;
para (i = 0; i < 13; i++)
para (j = 0; j < 13; j++)
{
/ / E y EC realizan la operación de redondeo hacia abajo
if (Input1_Terms_Membership[Input1_Terms_Index][i] <Input2_Terms_Membership[Input2_Terms_Index][j])
R1[i][j] = Input1_Terms_Membership[Input1_Terms_Index][i];
else
R1[i][j] = Input2_Terms_Membership[Input2_Terms_Index][j];
//Convierte la matriz R1 en un vector unidimensional R2
R2[k] = R1[i][j];
k++;
}
////<A=Input1_Terms_Membership[Input1_Terms_Index] ,B=Input2_Terms_Membership[Input2_Terms_Index]
// para (i = 0; i < 169; i++) for (j = 0; j < 13; j++) { // R1(E, EC) usa U para la operación de redondeo< / p> if (R2[i] < Output_Terms_Membership[Output_Terms_Index][j]) R3[i][j] = R2[i]; si no p> R3[i][j] = Output_Terms_Membership[Output_Terms_Index][j]; // R realiza la operación máxima en las conexiones de todas las relaciones difusas regulares si (R3[i][j] > R[i][j]) R[i] [j] = R3[i][j]; } } } /********************* ********* Para E y Cada valor exacto posible de EC se difusa y luego se infiere para obtener la salida difusa Cd, Cd=(AdxBd)oR************** ********** * */ para (Input1_value_index = 0; Entrada1_value_index < 13; Entrada1_value_index++) { para (Input2_value_index = 0; Entrada2_value_index < 13 ; Input2_value_index++) { for (j = 0; j < 13; j++) Cd[j] = 0; int kd = 0; float temp = 0; Max_ Input1_value = E_MAX(Input1_value_index); ///<Encontrar el valor de idioma con la mayor membresía de error Max_Input2_value = EC_MAX(Input2_value_index); / // para (i = 0; i < 13; i++) f o (j = 0; j < 13; j++) { // E(Ad) y EC(Bd) realizan la operación decimal si (Input1_Terms_Membership[Max_Input1_value][i] <Input2_Terms_Membership[Max_Input2_value][j]) AdBd1[i][j] = Input1_Terms_Membership[Max_Input1_value][i]; else AdBd1[i][j] = Input2_Terms_Membership[Max_Input2_value][j]; AdBd2[kd] = AdBd1[i][j]; kd++; } para (i = 0; i < 169; i++) para (j = 0; j < 13; j++) { //Sintetiza la matriz difusa, cambia la operación del producto a "tomar la más pequeña" y la operación de suma a "tomar la más grande" if ( AdBd2[i] <R[i][j]) temp = AdBd2[i]; else temp = R[i][j]; si (temp > Cd[j]) Cd [j] = temp; } /* ********************** La defusificación (método de promedio ponderado) calcula la salida real************* ***** **********/ flotante suma1 = 0, suma2 = 0; flotante FUERA; para (i = 0; i < 13; i++) { suma1 = suma1 + Cd[i]; suma2 = suma2 + Cd[i] * VELOCIDAD[i] ; } SALIDA = (int)(suma2 / suma1 + 0.5);////< Redondeo Fuzzy_Table[Input1_value_index ][Input2_value_index] = OUT; cout << OUT << ","; } cout << endl; }}12345678910111213141516171819202122232425262728293031323334353637383940 414243444546474849505152535455565758596061626364 65666768697071727374757677787980818283848586878889909192949596979899100101 1021031041051061071081091101111121131141151161171 18119120121122123124 3. Tabla de búsqueda difusa para establecer la velocidad Copie la tabla de búsqueda difusa en el programa de código y luego asigne los e y ec reales al argumento. , mira Busque el resultado en la tabla de búsqueda difusa y establezca la velocidad objetivo. int_16 Fuzzy_Table[13][13]= { 203,211,211,211,211,226,226,230,230,228,210,210,210,210,210,209,221,221,221,221,2 3 8,238,241,241,241,237,231,231, 231,227,209,221,221,221,238,238,241,241,237,231,231,231,227,209,221,221,221,238,238,241,24 1, 241.237.231.231.231.231.227.215.238.238, 238.238.245.245.266.266.246.237.237.237.232.215.238.238.238.245.245.266.266.246 7,237,237,237,238,218,250,250,250,276,276,283,283,280,245,245,245,216,218,250,250,250,276,276,283,283,280,245,245,245, 216,232,240,240,240,250,250,271,271,246,236,236,236,217,226,230,230.230,236,236,239,239,236,214,214,214,208,226,230,230,2 30,236,236,239,239,236,214,214,214,208,226,230,230,230,236,23 6,239,239,239,236.214,214,214,208,211,211,211,211,211,226,226, 230,230,228,208,208,208,208,203}?;int_16 get_speed_set (void) { int_16 E = 0, EC = 0; int_16 speed_target; p> static int_16 re_pos = 0, ek = 0, eck = 0 ; float ke = 400, kec = 10 ek = 2500 - fila ; p> eck = 2500 - fila - re_pos; re_pos = ek; if (ek > 0) { E = (int_32) (ek/ke + 0,5); } p> else { E = (int_32)(ek/ke - 0,5); } // Convertir el dominio de E a Dominio del controlador difuso si (E > 6) E = 6; si no (E < -6) E = -6; si (eck > 0) { EC = (int_16)( eck/kec + 0,5); } p> else { EC = (int_16)(eck/kec - 0,5); } } } Convierta el dominio de EC al dominio del controlador difuso si (EC > 6) CE = 6;< /p> si no (EC < -6) EC = -6; speed_target = (int_16)(Fuzzy_Table[E + 6][EC + 6] ); return speed_target ;}1234567891011121314151617181920212223242526272829303132333435363739404143444546474849505152535455 Ajustar parámetros y completar PID Buen trabajo~