Не выполянется созданая функция

Dragal
Offline
Зарегистрирован: 04.09.2015

Здравствуйте ,

Подскажите пожалуйста, почему не выполняется функция "pid" в 254 строке кода.

Все данные вхлдные есть. Единственное я заметил, что коэффициент "K" всегда ноль. Хотя в настройках равен 1.0.

#include <Kalman.h>

#include <I2Cdev.h>



  // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// ------------  Программа для расчета угла наклона по данным гироскопа и ускорения с использованием фильтра Калмана ----------------------------------
// --------------------------  и PID-регулирование для последовательного управления двумя двигателями драйверами Sabertooth -----------------------------------------------
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------


#include "Wire.h"
#include <TroykaIMU.h>   // ЭТО Я УЖЕ ОТ СЕБЯ БУДУ ДОБАВЛЯТЬ 
#include <math.h>
#include <SoftwareSerial.h>         // ХЗ Я ЕЩЕ НЕ ПОРЕДЕЛИЛСЯ С ДРАЙВЕРОМ
#include <SabertoothSimplified.h>   // С БИБЛИОТЕКОЙ СООТВЕТСТВЕННО ТОЖЕ

SoftwareSerial SWSerial(NOT_A_PIN, 11);          // RX on no pin (unused), TX on pin 11 (to S1). ЭТО ВСЕ К ТОЙ ЖЕ БИБЛИОТЕКЕ ОТНОСИТСЯ
SabertoothSimplified ST(SWSerial);               // Use SWSerial as the serial port.

Gyroscope gyro;            // СОЗДАЛИ ОБЬЕКТ ДЛЯ РАБОТЫ С ГИРИКОМ
                           // создаём объект для работы с акселерометром
Accelerometer accel;


#define Pin_Lenkung_rechts      12               // Штыревой разъем для команды управления Вправо
#define Pin_Lenkung_links       13               // Штыревой разъем для команды управления ВЛЕВО

#define Pin_Schalter_Box        3                // ПИН КОРОБКИ ВЫКЛЮЧАТЕЛЕЙ ДЛЯ ПЕРЕКЛЮЧЕНИЯ МЕЖДУ СИНХРОНИЗАЦИЕЙ МОТОРОВ И I-УПРАВЛЕНИЕМ

#define Pin_PID_Regelung_P      A1               // Контактный разъем для потенциометра для изменения P-компонента
#define Pin_PID_Regelung_I      A2               // Контактный разъем для потенциометра для изменения I-компонента
#define Pin_PID_Regelung_D      A3               // Контактный разъем для потенциометра для изменения D-компонента


int LoopTime_Soll = 9;                           // Желаемое время измельчения в мс для достижения 100 Гц      
int LoopTime_Angepasst = LoopTime_Soll;          // Последнее время цикла с принудительной паузой
int LoopTime_Bisher = LoopTime_Soll;             // Последнее время цикла без принудительного перерыва
unsigned long LoopTime_Start = 0;		             // ВРЕМЯ НАЧАЛА ЦИКЛА

float Winkel;					                           // Текущий угол наклона
float Winkel_Soll;                               // Уставка угла наклона, т. Е. 0 °
float Winkel_Grenze;                             // Максимально разрешенный угол наклона, над которым Segway выключен   
float Winkel1;


float ACC_angledraga;                            // Угол датчика ускорения ТРОЙКА
float GYRO_ratedraga;                            // Угол датчика Гироскопа Тройка
                           // Угол датчика Гироскопа Тройка

float Kp,Ki,Kd,K;                                // Константы для ПИД-регулирования, Разная деталь, Интегральная часть, Дифференциальная часть, Общая часть
int Motor;                                       // От ПИД-регулятора до управления двигателем
int Motor_rechts, Motor_links;                   // Значения для двух двигателей
float K_Motor_links, K_Motor_rechts;             // Коэффициенты коррекции синхронной работы двух двигателей

int Schalter_Box;                                // Переменная, которая запрашивает положение переключателя на коробке

int Lenkung_Eingang_rechts = 0;                  // Переменная для определения команды управления вправо
int Lenkung_Eingang_links = 0;                   // Переменная для определения команды управления ВЛЕВО
float Lenkung_max;                               // Значение, с помощью которого управление двигателем должно изменяться как максимальное значение для команды управления
float Lenkung_rechts, Lenkung_links;             // Текущее и ступенчатое увеличение контрольного значения при управлении вправо или влево

// ****************************************************************************
// ****************************** SETUP ***************************************
// ****************************************************************************


void setup()
   {
    Wire.begin(); 
     
    //SWSerial.begin(9600);     // This is the baud rate you chose with the DIP switches.
     
    Serial.begin(9600);    // baud rate für den seriellen Monitor, um die Werte zu überprüfen
    
    // initialize device
       //Подпрограмма для однократной калибровки датчиков
         // инициализация гироскопа
  gyro.begin();
  // инициализация акселерометра
  accel.begin();
   }





// ***********************************************************************************
// ****************************** Kalibrierung ***************************************
// ***********************************************************************************


void calibrateSensors()              //Одноразовое определение значений нуля датчика (среднее значение от 50 измерений в каждом случае)
   {
    
    // =================================================
    // ======== Изменение разрешения датчика ==========
    // =================================================
    
    // ===========================================================================
    // read raw accel/gyro measurements from device
    // Выходной сигнал: Разрешение 2g: 16384 / g Разрешение 4g: 8192 / g
    //  Выходной гироскоп: Разрешение 250 ° / с: 131 / ° / с Разрешение 500 ° / с: 65,5 / ° / с
    // ===========================================================================
    
     
    
    // Попытка избежать «погремушки» двух двигателей в начале
    
    ST.motor(1, 0);             
    ST.motor(2, 0);
    
   
        
    Winkel_Soll = 0.0;                 // Уставка для угла наклона
    Winkel_Grenze = 30.0;              // Максимально допустимый угол наклона
    
    
    // *******************************************************
    // ********** K - Werte für die PID-Regelung *************
    // *******************************************************
    
    
    Kp = analogRead(Pin_PID_Regelung_P) * 25.0 / 1023.0;        // Разница с фиксированным Поти
    Ki = 0.1;                                                   // Встроенная часть с потенциометром (переключатель, но, возможно, для коррекции двигателя, поэтому сначала установите 0,1)   
    Kd = analogRead(Pin_PID_Regelung_D) * 100.0 / 1023.0;       // Дифференциальная часть с потенциометром
    K = 1.0;                                                    // общая доля


    // **************************************************
    // ********** K - значения для ПИД-регулятора *************
    // **************************************************


   
         
    pinMode(Pin_Schalter_Box, INPUT); // Pin для выбора между I-управлением и синхронизацией двигателя

    
    K_Motor_rechts = 1.0;                  // Korrekturfaktor für den rechten Motor
    K_Motor_links = 0.8;                   // Korrekturfaktor für den linken Motor
      
    
    // **********************************************
    // ********** Рулевые значения *************
    // **********************************************
    
    
    Lenkung_max = 25.0;                      // Значение, с помощью которого управление двигателем должно измениться с помощью команды управления MAXIMAL
    Lenkung_rechts = 0.0;                    // Текущее дополнительное значение в процессе рулевого управления вправо
    Lenkung_links = 0.0;                     // Текущее дополнительное значение в процессе рулевого управления влево
    pinMode(Pin_Lenkung_rechts, INPUT);      // Вывод для рулевого управления ВПРАВО объявляется как вход
    pinMode(Pin_Lenkung_links, INPUT);       // Вывод для рулевого управления ВЛЕВО объявляется как вход
      
   }






// ***************************************************************************************************************************************************
// ***************************************************************************************************************************************************
// ********************************************************************** HAUPTSCHLEIFE **************************************************************
// ***************************************************************************************************************************************************
// ***************************************************************************************************************************************************

void loop()
   {

   // *******************************************************
   // ********************* Sensorabfrage *******************
   // *******************************************************
   
    // ===========================================================================
    // read raw accel/gyro measurements from device
    // Ausgabewerte-Acc: Auflösung 2g:  16384/g    Auflösung 4g:  8192/g
    // Ausgabewerte-Gyro: Auflösung 250°/s:  131/°/s   Auflösung 500°/s:  65.5/°/s
    // ===========================================================================
    Serial.print("    ACC_angledraga = ");
    Serial.print(ACC_angledraga);
    Serial.print("    motor : ");
    Serial.print(Motor);
    Serial.print("    Winkel: ");
    Serial.print(Winkel,0);       
    Serial.print("    Winkel_Soll : ");
    Serial.print(Winkel_Soll);       
    Serial.print("    GYRO : ");
    Serial.print(GYRO_ratedraga) ;
    Serial.print("    Kp : ");
    Serial.print(Kp) ;   
    Serial.print("    Kd : ");
    Serial.print(Kd) ;   
    Serial.print("    Ki : ");
    Serial.print(Ki) ; 
    Serial.print("    Schalter : ");
    Serial.print(Schalter_Box) ;
    Serial.print("    K : ");
    Serial.println(K);
                          // ЕБАННАЯ БИБЛИОТЕКА ДРУГОГО ДАТЧКИА
 
    
    ACC_angledraga = atan2(accel.readAX(),accel.readAZ()) * 180.0 / 3.141592654;      // МОЯ КРАСАВИЦА
    GYRO_ratedraga = gyro.readDegPerSecY();

     
     
   // *******************************************************
   // ********** K - значения для ПИД-регулятора *************
   // *******************************************************
    
    
    Kp = analogRead(Pin_PID_Regelung_P) * 25.0 / 1023.0;                     // Разница с Поти фиксирована; Максимум = 25. КОРОЧЕ МАКСИМАЛЬНЫЕ ЗНАЧЕНИЯ ДЛЯ НАСТРОЕК НЕ БОЛЬШЕ 25 И 100
    Kd = analogRead(Pin_PID_Regelung_D) * 100.0 / 1023.0;                    // Дифференциальное соотношение с потенциометром; Максимум = 100

    Schalter_Box = digitalRead(Pin_Schalter_Box);                            // Запросить контакт для состояния переключателя на коробке
    
    if (Schalter_Box == HIGH)                                                // С помощью переключателя на активированном ящике я управляю
       {
        Ki = analogRead(Pin_PID_Regelung_I) * 2.0 / 1023.0;                  // Интегральная часть с потенциометром; Максимум = 2        
       }
    else                                                                     // С помощью переключателя включено управление двигателем коробки
        {
         K_Motor_rechts = analogRead(Pin_PID_Regelung_I) * 2.0 / 1023.0;     // Коэффициент коррекции для синхронной работы двух двигателей; Максимум = 2
        }

      
     
     
     // ********************************************************************************
     // ****************** Фильтр Калмана, расчет PWM и значения двигателя *****************
     // ********************************************************************************
     
     
     Winkel = kalmanCalculate(ACC_angledraga, GYRO_ratedraga, LoopTime_Angepasst);	// Рассчитано с помощью фильтра Калмана
                                                                                    

     if (Winkel > Winkel_Grenze || Winkel < (Winkel_Grenze * (-1)))
        {
         // ===============================================
         // Снос из-за слишком большого угла наклона!
         // ===============================================
         
         ST.motor(1, 0);          //ОТКЛЮЧИТЬ НАХЕР ОБА МОТОРА
         ST.motor(2, 0);
        }
     else
        {
         // =========================
         // УГОЛ НАКЛОНА В ПОРЯДОСЕ 
         // =========================
 
         Motor = pid(Winkel, Winkel_Soll, GYRO_ratedraga);  // Расчет значения ШИМ для управления двигателями // НЕЗАБУДЬ ЧТО ЭТО ДЛЯ ТРОЙКИ УДАЛИ DRAGA 
     
         Motor_rechts = K_Motor_rechts * Motor;            // Расчет скорости двигателя, синхронизированный коэффициентом K, для правого двигателя

         Motor_links = K_Motor_links * Motor;              // Расчет скорости двигателя, синхронизированный коэффициентом K, для левого двигателя
     
         
          
         // **************************************************************************************
         // ***** Проверьте, активировано ли рулевое управление и измените управление двигателем *****
         // **************************************************************************************
     
     
         Lenkung_Eingang_rechts = digitalRead(Pin_Lenkung_rechts);   // Abfrage des Pins für Lenkung nach Rechts

         if (Lenkung_Eingang_rechts == HIGH)
            {     
              // ******************************************
              // *** Lenkung nach Rechts wurde gedrückt ***
              // ******************************************
          
              if (Motor_rechts >= 0)    // segway fährt gerade vorwärts oder steht. Welcher Motor abgefragt wird, ist egal.
                 {
                  Motor_rechts = Motor_rechts - (int)Lenkung_rechts;   // Возможно, также попробуйте с умножением вектора (например, * (1 - 0,1)
                  Motor_links = Motor_links + (int)Lenkung_rechts;     // Возможно, попробуйте также умножить вектор (например, * (1 + 0,1))
                 }
              else                      // segway fährt gerade rückwärts
                 {
                  Motor_rechts = Motor_rechts + (int)Lenkung_rechts;   // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 + 0.1) versuchen
                  Motor_links = Motor_links - (int)Lenkung_rechts;     // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 - 0.1) versuchen
                 }
                 
             Lenkung_rechts = Lenkung_rechts + 0.05;                                 // Лучше только для, например, Увеличьте 0,1 на запрос, чтобы рулевое управление не было слишком резким!
             
             if (Lenkung_rechts > Lenkung_max) Lenkung_rechts = Lenkung_max;        // Максимальное значение рулевого управления не должно превышаться!
             
             //Lenkung_rechts = constrain(Lenkung_rechts, 0, Lenkung_max);          // Правое значение рулевого управления используется в интервале [0, рулевое управление]
            } 
         else
            {
             Lenkung_rechts = 0.0;
            }
    
    
         Lenkung_Eingang_links = digitalRead(Pin_Lenkung_links);    // Abfrage des Pins für Lenkung nach Links

         if (Lenkung_Eingang_links == HIGH)
            {     
              // *****************************************
              // *** Lenkung nach Links wurde gedrückt ***
              // *****************************************
          
              if (Motor_links >= 0)    // segway fährt gerade vorwärts oder steht. Welcher Motor abgefragt wird ist egal.
                 {
                  Motor_rechts = Motor_rechts + (int)Lenkung_links;   // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 + 0.1) versuchen
                  Motor_links = Motor_links - (int)Lenkung_links;     // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 - 0.1) versuchen
                 }
              else                      // segway fährt gerade rückwärts
                 {
                  Motor_rechts = Motor_rechts - (int)Lenkung_links;   // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 - 0.1) versuchen
                  Motor_links = Motor_links + (int)Lenkung_links;     // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 + 0.1) versuchen
                 }
                 
             Lenkung_links = Lenkung_links + 0.05;                                 // Besser nur um z.B. 0.1 pro Abfrage erhöhen, damit Lenkung nicht zu abrupt erfolgt!
             
             if (Lenkung_links > Lenkung_max) Lenkung_links = Lenkung_max;        // Maximaler Lenkungswert darf nicht überschritten werden!
             
             //Lenkung_links = constrain(Lenkung_links, 0, Lenkung_max);          // linker Lenkungswert ins Intervall [0,Lenkung_max] gebracht
            } 
         else
            {
             Lenkung_links = 0.0;
            }
       
        
        
     
         // *******************************************************************************************
         // ******************************** Управление двигателями  ***********************************
         // *******************************************************************************************
        
         
         Motor_rechts = constrain(Motor_rechts, -127, 127);          // Значение правого двигателя в интервале [-127,127]
         Motor_links = constrain(Motor_links, -127, 127);            // Значение левого двигателя в интервале [-127,127]
         
                      
     /*
         // Использование функции корня вместо функции линейного привода для улучшения реакции при низких значениях двигателя
         // ======================================================================================================================================
         
         if (Motor_rechts >= 0)     // rechter Motor dreht vorwärts
            { 
             Motor_rechts = sqrt(127 * Motor_rechts);             // Чтобы улучшить реакцию при низких значениях двигателя
              
             ST.motor(2, Motor_rechts);      
            }
         else                       // rechter Motor dreht rückwärts
            {
             Motor_rechts = -sqrt(127 * -Motor_rechts);           // zur Verbesserung des Ansprechverhaltens bei niedrigen Motorwerten
             
             ST.motor(2, Motor_rechts);               
            }


         if (Motor_links >= 0)      // linker Motor dreht vorwärts
            {
             Motor_links = sqrt(127 * Motor_links);               // zur Verbesserung des Ansprechverhaltens bei niedrigen Motorwerten 
             
             ST.motor(1, Motor_links);               
            }
         else                       // linker Motor dreht rückwärts
            {
             Motor_links = -sqrt(127 * -Motor_links);             // zur Verbesserung des Ansprechverhaltens bei niedrigen Motorwerten 
             
             ST.motor(1, Motor_links);  
            }
         */
         
         ST.motor(1, Motor_links);
         ST.motor(2, Motor_rechts);
         
        } 


   // ************************************************************************ 
   // ***********************   Выход измеряемых величин **************************
   // ************************************************************************

    Werteausgabe();


   // ******************************************************************
   // *********************** Tastaturabfrage **************************
   // ******************************************************************

   // Tastatureingabe();



   // **********************************************************************
   // *********************** loop timing control **************************
   // **********************************************************************

     LoopTime_Bisher = millis() - LoopTime_Start;        // Время с момента последнего цикла
     
     if(LoopTime_Bisher < LoopTime_Soll)
        {
         delay(LoopTime_Soll - LoopTime_Bisher);         // Задержка для получения того же времени цикла
        }
     
     LoopTime_Angepasst = millis() - LoopTime_Start;     // Обновленная длительность последнего цикла должна равняться LoopTime_Soll = например. 10 мсек!
     LoopTime_Start = millis();                          //Новый запуск цикла
   
 }


// ********************************************************************************************
// ****************** Вывод на последовательный интерфейс ******************************
// ********************************************************************************************

void Werteausgabe()
   {
    /*
    Serial.print(Winkel);
    Serial.print("     ");
    Serial.println(Motor);
    Serial.print("     ");
    */
    

    
    /*
    Serial.print("   Motor: ");
    Serial.print(Motor);
    Serial.print("    Motor_rechts: ");
    Serial.print(Motor_rechts);
    Serial.print("    Motor_links: ");
    Serial.println(Motor_links);
    */
    
   }


// ******************************************************************************************************
// ***************************************** PID-Steuerung **********************************************
// ******************************************************************************************************

float error;
float last_error = 0;
float pTerm;
float iTerm;
float dTerm;
float integrated_error = 0;
int GUARD_GAIN = 40;           // Максимальная угловая погрешность

   int pid(float Winkel_aktuell, float Winkel_Vorgabe, float Winkelgeschwindigkeit)
      {
       error = Winkel_Vorgabe - Winkel_aktuell;
       
       pTerm = Kp * error;                                                         // Differenzenanteil
       
       integrated_error = integrated_error + error;
   
       iTerm = Ki * constrain(integrated_error, -GUARD_GAIN, GUARD_GAIN);          // Integralanteil
  
       
       dTerm = Kd * Winkelgeschwindigkeit / 100.0;                                 // Дифференциальный компонент; : 100 для достижения полезных значений!  
  
       last_error = error;
       
       return constrain(K*(pTerm + iTerm + dTerm), -127, 127);                     // Выходное значение двигателя для двух двигателей в пределах [-127,127]
      } 

 
 

// ******************************************************************************************************
// ************************************** Kalman filter module ******************************************
// ******************************************************************************************************


    float Q_angle  =  0.001;		// E(alpha2) = 0.001
    float Q_gyro   =  0.003;  		// E(bias2) = 0.003
    float R_angle  =  0.001;  		// Sz = 0.03   !!! je größer die Zahl, desto unempfindlicher reagiert der Winkel auf Veränderungen !!!
    float x_angle = 0;
    float x_bias = 0;
    float P_00 = 0, P_01 = 0, P_10 = 0, P_11 = 0;
    float dt, y, S;
    float K_0, K_1;

  float kalmanCalculate(float newAngle, float newRate, int looptime)
     {
      dt = float(looptime)/1000;    // dt in Sekunden
      x_angle = x_angle + dt * (newRate - x_bias);
      P_00 = P_00 - dt * (P_10 + P_01) + Q_angle * dt;
      P_01 = P_01 - dt * P_11;
      P_10 = P_10 - dt * P_11;
      P_11 = P_11 + Q_gyro * dt;

      y = newAngle - x_angle;
      S = P_00 + R_angle;
      K_0 = P_00 / S;
      K_1 = P_10 / S;

      x_angle +=  K_0 * y;
      x_bias  +=  K_1 * y;
      P_00 -= K_0 * P_00;
      P_01 -= K_0 * P_01;
      P_10 -= K_1 * P_00;
      P_11 -= K_1 * P_01;

      return x_angle;
     }



// ********************************************************************
// ******** Запрос клавиатуры для изменения параметров PUI *********
// ********************************************************************

int Tastatureingabe()
   {
    if(!Serial.available())    return 0;
   
    char param = Serial.read();                            // get parameter byte
  
    if(!Serial.available())    return 0;
  
    char cmd = Serial.read();                              // get command byte
  
    Serial.flush();
  
    switch (param)
       {
        case 'p':
           if(cmd=='+')    Kp++;
           if(cmd=='-')    Kp--;
           break;
        case 'i':
           if(cmd=='+')    Ki += 0.1;
           if(cmd=='-')    Ki -= 0.1;
           break;
        case 'd':
           if(cmd=='+')    Kd++;
           if(cmd=='-')    Kd--;
           break;
       case 'k':
           if(cmd=='+')    K += 0.2;
           if(cmd=='-')    K -= 0.2;
           break;
       case 'l':
           if(cmd=='+')    K_Motor_links += 0.1;
           if(cmd=='-')    K_Motor_links -= 0.1;
           break;
       case 'r':
           if(cmd=='+')    K_Motor_rechts += 0.1;
           if(cmd=='-')    K_Motor_rechts -= 0.1;
           break;
     
       default:
           Serial.print("?");           Serial.print(param);
           Serial.print(" ?");          Serial.println(cmd);
      }
  
    Serial.println();
    Serial.print("K:");                      Serial.print(K);
    Serial.print("   Kp:");                  Serial.print(Kp);
    Serial.print("   Ki:");                  Serial.print(Ki);
    Serial.print("   Kd:");                  Serial.print(Kd);
    Serial.print("   K_Motor_links:");       Serial.print(K_Motor_links);
    Serial.print("   K_Motor_rechts:");      Serial.println(K_Motor_rechts);
   } 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А кто Вам сказал, что она не выполняется? Если компилируется, то и выполняется. Поставьте печати перед вызовом и внутри и убедитесь.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Dragal пишет:
Единственное я заметил, что коэффициент "K" всегда ноль. Хотя в настройках равен 1.0.

У Вас К изначально равен 0. Единица ему присваивается в процедуре calibrateSensors, которую Вы нигде не вызываете. Потому и нулевое значение...

Dragal
Offline
Зарегистрирован: 04.09.2015

Motor в 254 строке у меня всегда равен нулю. То есть фунция "pid" всегда возвращает ноль. Все давнные входные есть и с датчиков и с потенциметров.

Dragal
Offline
Зарегистрирован: 04.09.2015

OlegK пишет:

Dragal пишет:
Единственное я заметил, что коэффициент "K" всегда ноль. Хотя в настройках равен 1.0.

У Вас К изначально равен 0. Единица ему присваивается в процедуре calibrateSensors, которую Вы нигде не вызываете. Потому и нулевое значение...

464       return constrain(K*(pTerm + iTerm + dTerm), -127, 127);

Так как он всегда 0, то и возвращает 0-ое значение? Код заимствованый, и я не могу понять в данной ситуации, от чего вообще зависит знгачение коэффициента "K".

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Dragal пишет:
464Так как он всегда 0, то и возвращает 0-ое значение?

А ожидаете получить что-то другое, умножая на 0?

Цитата:
от чего вообще зависит знгачение коэффициента "K".

Повторюсь.
В вашем случае "К" всегда равен 0.
Потому что:
Вы её объявили без инициализации, оответственно, "К" равно 0.
Далее есть процедура calibrateSensors, в которой переменной К присваивается значение 1.
Но эта процедура нигде не используется,а потому значение К так и останется равным 0, равно как всегда будут раны 0 и переменные - Kp,Ki,Kd (которые почему-то обозваны константами). И даже ручная подстройка через сериал не спасёт - она закомментирована и потому не работает.

ЗЫ. А ещё и пропорциональный коэффициент Kp обозван "разная деталь"... В общем, печально всё ))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Dragal пишет:

Motor в 254 строке у меня всегда равен нулю. То есть фунция "pid" всегда возвращает ноль. Все давнные входные есть и с датчиков и с потенциметров.

Так значит она у Вас выполняется, просто её результат Вам не нравится? Ну и нафига было писать "не выполняется"? Написали бы сразу про 0, уже бы проблему решили.

Ну, что, вместо строки 464 пишем следующее:

  const int result = constrain(K * (pTerm + iTerm + dTerm), -127, 127);
  Serial.print("pTerm="); Serial.println(pTerm);
  Serial.print("iTerm="); Serial.println(iTerm);
  Serial.print("dTerm="); Serial.println(dTerm);
  Serial.print("result="); Serial.println(result);
  Serial.println("-----------------------");
  return result;    

И смотрим, что напечатает. Скорее всего всё станет понятным. Если не станет, то выкладываем сюда новый скетч и выданный результат.

UPDATE: прочитал пост OlegK  - он 100% прав. Исправляйте, а про мой совет пока забудьте. Если после исправления результат по-прежнему не будет нравиться, то вернётесь к моему совету.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Dragal пишет:

я не могу понять в данной ситуации, от чего вообще зависит знгачение коэффициента "K".

Ну, то, что код не Ваш - понятно, но хотя бы понимать общую идею Вы должны!

Коэфциент К зависит от фантазии Вашей левой пятки при взгляде на потолок через правое ухо и ни от чего другого, т.е. попросту он подбирается под задачу. Откройте гугл и почитайте что-нибудь про ПИД-регулирование, там про этот коэффициент всё написано.

Dragal
Offline
Зарегистрирован: 04.09.2015

В серийный монитор ничего не печает. Может из-за того, что команды располагаются в процедуре?

b707
Offline
Зарегистрирован: 26.05.2017

Dragal пишет:

В серийный монитор ничего не печает. Может из-за того, что команды располагаются в процедуре?

"дело было не в бобине..."

Из процедуры тоже должно печатать - если код рабочий.

Dragal
Offline
Зарегистрирован: 04.09.2015

"дело было не в бобине..."

Блин угарно конечно, я уверен) Но тем не менее , не прнимаю почему не печатает.

Например следуемая за фукцией loop функция Werteausgabe выводится в серийный монитор

void Werteausgabe()
   {
    
    Serial.print(Winkel);
    Serial.print("     ");
    Serial.println(Motor);
    Serial.print("     ");
    
    
   }

А из идущей следом процедуры  - нет.

b707
Offline
Зарегистрирован: 26.05.2017

Dragal пишет:

Блин угарно конечно, я уверен) Но тем не менее , не прнимаю почему не печатает.

значит ваша функция pid не вызывается.  Ее вызов у вас стоит в блоке else (строка 249), видимо в этот блок программа не заходит.

Добавьте еще диагностическую печать в соответсвующий блок if и else

 

ЗЫ поражают люди, не умея программировать, сразу хватаются за программы в сотни строк. Начинайте с мигания диодом...

Dragal
Offline
Зарегистрирован: 04.09.2015

Точно.

В else (248 строка ) не заходил, так как Winkel_Grenze  (239 строка), всегда была равна нулю. А нулю она была равна по той же причине, что и "K": им присваивались значение в функции calibrateSensors() (94 строка). Перенес это присвоение в функцию Setup. Теперь работает.

Dragal
Offline
Зарегистрирован: 04.09.2015

OlegK]</p> <p>[quote=Dragal пишет:
она закомментирована и потому не работает.

Что это означает фактически, как ее "раскоментировать"?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Фактически означает, что вызов функции Tastatureingabe, которая принимает из сериал порта параметры для подстройки ПИД-коэффициентов отключён комментарием в строке 389. Раскомментировать - удалить "две косые палки"

ЗЫ.
>>от чего вообще зависит знгачение коэффициента "K". N
От фантазии автора исходника - этот коэфф. к ПИД-регулированию никак не относится, т.к. вышеуказанный принцип регулирования складывается из суммы пропорциональной (Kp), интегральной (Ki) и дифференциальной(Kd) составляющих и должен нормально работать при правильном подборе этих коэффициентов. Нафига умножать на "К" - хз...

Можете, если интересно, поискать в инете книжку в ПДФ "Карпов" "ПИД регулирование в нестрогом изложении"

b707
Offline
Зарегистрирован: 26.05.2017

Dragal пишет:

Что это означает фактически, как ее "раскоментировать"?

А на горшок за вас не сходить?

Через 2 дня пойдет третий год, как вы занимаетесь ардуиной... а до сих пор не знаете, как комментарии вставляют в программу7

Dragal
Offline
Зарегистрирован: 04.09.2015

Я тоже так подумал и удалил его.

Про Карпова слышал, спасибо зап совет.

И за помощь огромное спасибо.

Dragal
Offline
Зарегистрирован: 04.09.2015

У меня был большой перерыв)))

Спасибо большое за помощь!

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Dragal пишет:

У меня был большой перерыв)))

Спасибо большое за помощь!

на свободу с чистой совестью

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

OlegK пишет:

 Нафига умножать на "К" - хз...

Это что-то вроде ФНЧ. Позволяет смягчить управление, т.е. замаскировать некоторую небрежность в выборе трёх коэффициентов.