2015-03-11 6 views
-1

Я написал в Nios 2 ad hoc cruise control system для школьного задания. Я выполнил его с помощью github. Мы хотим, чтобы круиз-контроль отличался не более 2 м/с для скоростей> = 25 м/с. Последнее улучшение, которое я мог сделать, это проверить скорости в состоянии, которое улучшило контроль. Я не мог доказать, прежде чем я попытаюсь, чтобы это изменение повлияло, поэтому это подход ad hoc для проб и ошибок, который не так хорош. Теперь круиз-контроль фактически удерживает spped в пределах 2 м/с, если он активирован. Что еще можно сделать сейчас, когда мне удалось это улучшить? Могу ли я использовать что-то из теории управления, чтобы вывести поведение?Как я могу улучшить свою систему круиз-контроля для Nios 2?

/* 
* The task 'ControlTask' is the main task of the application. It reacts 
* on sensors and generates responses. 
*/ 

void ControlTask(void* pdata) 
{ 
    INT8U err; 
    INT8U throttle = 40; /* Value between 0 and 80, which is interpreted as between 0.0V and 8.0V */ 
    void* msg; 
    INT16S* current_velocity; 
    int btn_reg; 
    INT16S* current_output; 
    printf("Control Task created!\n"); 

    while (1) 
    { 

     OSSemPend(aSemaphore, 1, &err); // Trying to access the key 
     msg = OSMboxPend(Mbox_Velocity, 0, &err); 
     current_velocity = (INT16S*) msg; 
     printf("Control Task!\n"); 
     ButtonIO(current_velocity, throttle); 
     btn_reg = IORD_ALTERA_AVALON_PIO_DATA(DE2_PIO_KEYS4_BASE); 
     printf("btn_reg %d\n", btn_reg); 
     if (btn_reg == 7) { 
      ++throttle; 
     } else if (cruise_control_increase_velocity == 1) { 
      printf("increase velocity \n"); 
      if (*current_velocity <= cruise_velocity) { 
       throttle = throttle + 15; 
      } 


      cruise_control_increase_velocity = 0; 
     } 
     else if (btn_reg == 11) { 
      if (throttle > 0) { 
       --throttle; 
      } 

     } else if (cruise_control_decrease_velocity == 1) { 
      printf("decrease_velocity \n"); 
      if (throttle >= 15 && current_velocity >= cruise_velocity) { 
       throttle = throttle -15; 

      } 
      cruise_control_decrease_velocity = 0; 
     } 
     if (btn_reg== 13) { 
      printf("do cruise control\n"); 
      cruise_velocity = *current_velocity; 
     } 
     Button1IO(current_velocity); 
     SwitchIO(current_velocity, getGlobalPosition()); 
     err = OSMboxPost(Mbox_Throttle, (void *) &throttle); 
    } 
} 
+1

, как часто эта задача выполняется? со всеми этими вызовами printf() время для одного выполнения будет довольно медленным. Скачок +/- 15 в настройке дроссельной заслонки может заставить текущую скорость реагировать быстро, но если задача выполняется часто, то, вероятно, это много. – user3629249

+1

, похоже, существует несколько глобальных переменных, таких как cruise_control_decrease-speed и cruise_control_increase_velocity и cruise_velocity. Все это было бы лучше сохранено в структуре и указателе на эту структуру, переданную этой задаче. – user3629249

+1

цикл while не имеет предельной скорости выполнения, поэтому он будет выполнять десятки/сотни раз в секунду. когда btn_reg указывает на желаемое изменение, настройка дроссельной заслонки изменится очень быстро, вероятно, не то, что вы хотите. предложите добавить какую-то предельную логику, так что цикл while выполняется только с некоторой периодической скоростью, скажем, 10 раз в секунду. текущий код не освобождает процессор, поэтому он будет запускать циклы процессора, в результате чего другие задачи будут потеряны в ЦП. Infact, без предварительного упреждающего планирования, ничего не может быть выполнено. – user3629249

ответ

1
  • Очевидно отделить задачу управления от ввода/вывода. Они имеют разные требования в режиме реального времени, и выполнение обоих задач в одном цикле задач может быть вредным для контроля стабильности; хотя с медленной системой реагирования, такой как автомобиль, это может быть не очень важно, но все же имеет смысл разделить эти действия с хорошим смыслом.

  • Используйте классический PID контур управления, где ошибка входа фактической скорость - целевой скорость, а выход положения дроссельной заслонки. Коэффициент усиления I (интегральный) обеспечивает достаточную дроссельную заслонку для поддержания скорости в установившемся режиме, коэффициент усиления 0 пропорционально увеличивает агрессивность ускорения. в то время как коэффициент D (производный) усиливает отклик, чтобы минимизировать перерегулирование/недокус, и улучшает реакцию на внезапные изменения, такие как холмы. При использовании асимметричной нелинейной системы с большим количеством гистерезиса настройка контура управления может быть непротиворечивой, и вам нужно избегать слишком агрессивного с коэффициентами. Однако чрезмерный затухающий ответ, вероятно, способствует комфорту пассажира и потреблению топлива. Ожидается, что термин «I» будет ограничен, чтобы предотвратить «зависание», что может привести, например, к внезапному ускорению при подъеме крутого холма, если целевая скорость не может быть тщательно отслеживается.

  • Avoid global variables. Код, размещенный снаружи на этом сайте, как в порядке 24 глобальных переменных.