Vòng điều khiển PID với sự bất thường lớn và không thể đoán trước


10

Câu hỏi ngắn
Có cách nào phổ biến để xử lý các dị thường rất lớn (thứ tự cường độ) trong một khu vực kiểm soát thống nhất khác không?

Bối cảnh
Tôi đang làm việc trên một thuật toán điều khiển điều khiển một động cơ trên một vùng điều khiển chung thống nhất. Với tải không / tối thiểu, điều khiển PID hoạt động rất tốt (phản hồi nhanh, ít hoặc không quá mức). Vấn đề tôi gặp phải là thường sẽ có ít nhất một vị trí tải cao. Vị trí được xác định bởi người dùng trong khi cài đặt, vì vậy không có cách nào hợp lý để tôi biết khi nào / nơi để mong đợi nó.

Khi tôi điều chỉnh PID để xử lý vị trí tải cao, nó sẽ gây ra các cú bắn lớn trên các khu vực không được tải (mà tôi hoàn toàn mong đợi). Trong khi đó là OK để vượt qua giữa du lịch, không có điểm dừng cứng cơ học trên bao vây. Việc thiếu hardstops có nghĩa là bất kỳ sự vượt quá đáng kể nào cũng có thể / không làm cho cánh tay điều khiển bị ngắt khỏi động cơ (mang lại một đơn vị chết).

Những điều tôi đang tạo mẫu

  • Các lồng nhau lồng nhau (rất khó chịu khi ở xa mục tiêu, bảo thủ khi ở gần)
  • Đã sửa lỗi tăng khi ở xa, PID khi đóng
  • PID bảo thủ (hoạt động không tải) + một điều khiển bên ngoài tìm kiếm PID bị đình trệ và áp dụng năng lượng bổ sung cho đến khi: mục tiêu đạt được hoặc tốc độ thay đổi nhanh chóng được phát hiện (nghĩa là rời khỏi khu vực tải cao)

Hạn chế

  • Xác định du lịch đầy đủ
  • Hardstops không thể được thêm vào (tại thời điểm này)
  • Lỗi có thể sẽ không bao giờ hết
  • Tải trọng cao có thể đạt được từ chuyến đi dưới 10% (nghĩa là không có "bắt đầu chạy")

Câu trả lời:


2

Tính toán lỗi của bạn dường như không tích lũy lỗi khi làm việc với thuật ngữ phái sinh và bạn có thể muốn sửa đổi điều này vì chỉ có thuật ngữ phái sinh mới có thể phản ứng với những thay đổi nhanh trong quy trình.

Nếu tôi hiểu đúng mã của bạn

// Determine the error delta
dE = abs(last_error - new_error);
last_error = new_error;

sẽ luôn tính toán thuật ngữ kiểm soát dựa trên lỗi hiện tại, đây là cách truyền thống về cách thức thực thi PID. Sẽ ổn thôi vì dù sao thì thuật ngữ tôi được coi là phải xử lý lỗi tích lũy.

Tuy nhiên, tôi đã có một khách hàng nghĩ ra ý tưởng sau đây mà bạn có thể muốn thử. Vì bạn có một phần của đường cong quy trình, nơi cần thay đổi mạnh mẽ hơn, bạn có thể để ngay cả lỗi phần D tích lũy:

if(TD)                                                 // Calculate D term
{  
   Last_C += (Error - Last_C) / TD;                    // D term simulates
   Dterm = (Error - Last_C) * KD;                      // capacitor discharging
}
else    
   Dterm = 0;                                          // D term is OFF (TD is 0)

Có hai điều thú vị cần lưu ý ở đây:

  • Giá trị TD không phải là mức tăng đạo hàm (là KD) mà là thời gian phái sinh, hằng số người dùng kiểm soát thời gian để lỗi tích lũy. Nếu nó được đặt thành 0, phần D của PID bị vô hiệu hóa bất kể bộ giá trị khuếch đại KD.

  • Lưu ý cách sử dụng lỗi hiện tại để 'tính phí' giá trị Last_C trước khi đưa nó vào tính toán phần D. Biến Last_C hoạt động giống như một tụ điện, nó sẽ tích tụ trong khi lỗi lớn, do đó phần phái sinh của bạn cũng sẽ hoạt động dựa trên 'lịch sử' lỗi gần đây và sau đó (khi lỗi nhỏ hơn) lịch sử này 'sẽ phóng điện như một tụ điện.

Tất nhiên, bạn nên giới hạn tổng sản lượng theo cách bạn có thể đã làm (thiết lập lại chống gió, tự động chuyển sang chế độ chuyển thủ công và các công cụ thông thường khác).

Tôi có thể đăng thêm chi tiết về các điều khoản khác của thuật toán PID của tôi nếu bạn thấy nó hữu ích, nhưng bạn có thể muốn thử điều này và xem điều gì sẽ xảy ra. Nó phục vụ khách hàng của tôi tốt trong nhiều năm.


Cảm ơn các đầu vào. Tôi sẽ phải thử cái này. Nhìn thoáng qua có vẻ có ý nghĩa.
Adam Lewis

Tôi hiểu rồi, vì vậy bạn có đóng góp hạn D trong phạm vi 'chính' của bạn cộng với bất kỳ phát hiện gian hàng nào mang lại cho phép tính.
Drazen Cika

1
Đúng rồi. Dterm của PID được sử dụng, tho không quá tích cực, trong quá trình điều chỉnh. Điều làm cho vấn đề này trở nên khó khăn hơn nữa là tải có thể thoát ra trong một khoảng thời gian rất ngắn. IE một liên kết được thảnh thơi. Việc loại bỏ lực đột ngột này gây ra các phần vượt quá lớn khi có bất kỳ chức năng làm mịn (tổng hợp) nào được áp dụng cho các lực lượng gian hàng.
Adam Lewis

Vấn đề xấu, sẽ rất thú vị khi biết một số thuật toán logic mờ sẽ xử lý việc này tốt như thế nào. Ít nhất bạn có thể xây dựng thêm kinh nghiệm liên quan đến vấn đề của mình vào thuật toán, thay vì chỉ giới hạn trong các giải pháp tiêu chuẩn. Dù sao, chúc may mắn với điều này :-)
Drazen Cika

1

Giải pháp ban đầu

stalled_pwmDefput = PWM / | | E |

PWM = Giá trị PWM tối đa
ΔE = last_error - new_error

Mối quan hệ ban đầu làm tăng thành công đầu ra PWM dựa trên việc thiếu thay đổi trong động cơ. Xem biểu đồ dưới đây cho đầu ra mẫu.

Cách tiếp cận này được thực hiện kể từ khi tình huống mà PID không tích cực bị đình trệ. Tuy nhiên, có một vấn đề đáng tiếc (và rõ ràng) là khi PID không tích cực có khả năng đạt được điểm đặt và cố gắng làm chậm, stalled_pwmDefput tăng tốc. Đoạn đường nối này gây ra tình trạng vượt quá lớn khi di chuyển đến vị trí không tải.

1 / vsE so với E

Giải pháp tạm thời

Học thuyết

stalled_pwmDefput = (kE * PID_PWM) / | | E |

kE = Chia tỷ lệ liên tục
PID_PWM = Yêu cầu PWM hiện tại từ PID không
gây căng thẳng ΔE = last_error - new_error

Mối quan hệ hiện tại của tôi vẫn sử dụng khái niệm 1 / ΔE, nhưng sử dụng đầu ra PID PWM không tích cực để xác định stall_pwmDefput. Điều này cho phép PID điều tiết trở lại stall_pwmDefput khi nó bắt đầu tiến gần đến điểm đặt mục tiêu, nhưng vẫn cho phép đầu ra 100% khi bị đình trệ. Hằng số tỷ lệ kE là cần thiết để đảm bảo PWM đi vào điểm bão hòa (trên 10.000 trong biểu đồ bên dưới).

Mã giả

Lưu ý rằng kết quả từ cal_stall_pwm được thêm vào đầu ra PID PWM trong logic điều khiển hiện tại của tôi.

int calc_stall_pwm(int pid_pwm, int new_error)
{
    int ret = 0;
    int dE = 0;
    static int last_error = 0;
    const int kE = 1;

    // Allow the stall_control until the setpoint is achived
    if( FALSE == motor_has_reached_target())
    {
        // Determine the error delta
        dE = abs(last_error - new_error);
        last_error = new_error;

        // Protect from divide by zeros
        dE = (dE == 0) ? 1 : dE;

        // Determine the stall_pwm_output
        ret = (kE * pid_pwm) / dE;
    }

    return ret;
}

Dữ liệu đầu ra

Ngõ ra PWM bị đình trệ Ngõ ra PWM bị đình trệ

Lưu ý rằng trong biểu đồ đầu ra PWM bị đình trệ, mức giảm đột ngột ở mức ~ 3400 là một tính năng an toàn tích hợp được kích hoạt do động cơ không thể đạt đến vị trí trong một thời gian nhất định.

Đầu ra PWM không tải Đầu ra PWM không tải


1

Bạn không nói những gì bạn đang kiểm soát ... tốc độ động cơ? Chức vụ? Dù đó là gì đi nữa, bước đầu tiên sẽ là xác định lỗi nào có thể chấp nhận được. Ví dụ: nếu điều khiển dành cho tốc độ, lỗi tối đa trong vòng 1% mục tiêu có thể được đặt. Nếu không xác định lỗi có thể chấp nhận, bạn không thể xác định mức độ phân giải bạn cần cho bộ đếm ADC hoặc PWM. Không có điều đó, bù trừ PID có thể là hoàn hảo, nhưng vẫn sẽ có dao động chu kỳ giới hạn.

Sau đó, bạn cần biết động lực học của hệ thống vòng lặp mở. Không có điều đó, bạn không thể biết mức tăng nào là cần thiết cho các phần tỷ lệ (P), tích phân (I) và đạo hàm (D) của vòng lặp. Bạn có thể đo động với bước đầu vào (bước thay đổi ở cấp ổ đĩa hoặc PWM) hoặc bước thay đổi về tải (có vẻ như điều này sẽ phù hợp với bạn).

Sử dụng thay đổi lỗi theo chu kỳ, theo mẫu số của thuật toán điều khiển của bạn, để sửa đổi giá trị PWM đảm bảo rằng vòng lặp sẽ không bao giờ giải quyết. Điều này đảm bảo dao động chu kỳ giới hạn trong điều khiển. Hầu hết khách hàng sẽ không chấp nhận điều đó.

Phần P của vòng lặp xử lý lỗi ngay lập tức (phản hồi lỗi kịp thời). Nhưng nó sẽ có mức tăng hữu hạn nên một số lỗi sẽ bị bỏ lại. Phần I của vòng lặp phản ứng chậm theo thời gian để áp dụng mức tăng vô hạn (thời gian vô hạn cho mức tăng vô hạn) để sửa lỗi đó do phần P còn lại.

Vì phần I chậm, nó có thể thoát khỏi pha với sự điều chỉnh cần thiết để giảm thiểu lỗi, ngay cả khi bạn đã đặt đúng mức tăng cho nó. Vì vậy, nó bị thương, mất nhiều thời gian để hồi phục. Hoặc, nó được để lại đối lập với phần P.

Cách tốt nhất để xử lý gió là giới hạn giá trị được lưu trữ tối đa trong bộ tích hợp chỉ hơn một chút so với mức cần thiết để sửa lỗi tỷ lệ trong trường hợp xấu nhất. Nếu bộ tích phân ra khỏi pha và đối lập với P ngoài, điều tốt nhất cần làm là đặt giá trị tích phân thành 0. Thuật toán có thể được thiết kế để cảm nhận điều này và thiết lập lại tích hợp khi cần thiết.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.