Việc triển khai thuật toán điều khiển dự báo mô hình (MPC) trong thực tế thường gặp nhiều rào cản kỹ thuật, đặc biệt khi kết hợp với phần mềm mô phỏng động lực học xe như Carsim. Bài viết này hướng dẫn từng bước xây dựng hệ thống mô phỏng hoàn chỉnh cho bài toán bám quỹ đạo kép (double lane change), từ cấu hình môi trường đến lập trình S-Function tối ưu.
1. Thiết lập môi trường mô phỏng liên kết
Trước khi bắt đầu, hãy đảm bảo hệ thống đã cài đặt đầy đủ:
- Carsim phiên bản 2019 trở lên (có hỗ trợ giao diện Simulink)
- Matlab R2019b hoặc mới hơn (ưu tiên R2020a để tương thích tốt với toolbox MPC)
- Bộ biên dịch C/C++ (Visual Studio 2017/2019 hoặc MinGW-w64)
Cấu hình biến môi trường là bước thiết yếu nhưng dễ bị bỏ qua. Trên Windows, thêm các đường dẫn sau vào biến PATH hệ thống:
- Thư mục cài đặt Carsim (ví dụ:
C:\Program Files\CarSim2021) - Thư mục solver của Carsim (ví dụ:
C:\ProgramFiles\CarSim2021\solvers) - Thư mục runtime của Matlab
Kiểm tra nhanh bằng cách chạy thử ví dụ mẫu trong thư mục Samples_General\Simulink của Carsim. Nếu mô phỏng chạy thành công mà không báo lỗi, môi trường đã sẵn sàng.
2. Cấu hình thông số xe trong Carsim
Để mô phỏng có độ tin cậy cao, cần hiệu chỉnh chính xác các thông số then chốt:
| Nhóm thông số | Thông số quan trọng | Giá trị đề xuất | Ghi chú |
|---|---|---|---|
| Khối lượng | Vehicle Mass | 1500 kg | Bao gồm cả tài xế và hành lý tiêu chuẩn |
| Lốp xe | Tire Model | Pacejka 2002 | Mô hình nửa thực nghiệm phổ biến nhất |
| Hệ thống treo | Suspension Type | Double Wishbone | Cho phép tính toán tải bánh xe chính xác hơn |
| Hệ thống lái | Steering Ratio | 16:1 | Tỷ số truyền lái điển hình cho xe du lịch |
| Khí động học | Drag Coefficient | 0.32 | Ảnh hưởng đến động lực học dọc ở tốc độ cao |
Trong mục "Send to Simulink", kích hoạt các tín hiệu đầu ra cần thiết cho bộ điều khiển:
- Vận tốc dọc (Vx)
- Vận tốc ngang (Vy)
- Tốc độ góc quay thân xe (yaw rate)
- Tọa độ vị trí X/Y
- Góc đánh lái hiện tại
3. Kiến trúc mô hình Simulink
Mô hình tổng thể gồm ba khối chức năng chính:
- Giao tiếp với Carsim: Module S-Function nhận/gửi dữ liệu
- Bộ điều khiển MPC: Thực thi thuật toán dự báo
- Hiển thị & giám sát: Theo dõi quỹ đạo và tín hiệu điều khiển
Để tạo quỹ đạo thay đổi làn kép, sử dụng đoạn mã sau trong Matlab:
% Tạo quỹ đạo thay đổi làn kép
distance = 0:0.1:300; % Quãng đường dọc (m)
lane_width = 3.5; % Chiều rộng làn đường (m)
transition_len = 30; % Chiều dài đoạn chuyển tiếp
% Tạo tín hiệu tham chiếu theo hàm tanh
ref_lateral = (lane_width/2) * [ ...
ones(1,100), ... % Giữ nguyên làn ban đầu
tanh(2*(distance(101:130)-transition_len/2)/transition_len), ... % Chuyển làn lần 1
-tanh(2*(distance(131:160)-3*transition_len/2)/transition_len), ... % Chuyển làn lần 2
zeros(1,140) ... % Trở về làn trung tâm
];
4. Triển khai bộ điều khiển MPC bằng S-Function
Dưới đây là phiên bản cải tiến của S-Function với logic điều khiển rõ ràng hơn và tên biến mang tính mô tả:
#define S_FUNCTION_NAME trajectory_tracker
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include "math.h"
// Hằng số cấu hình MPC
#define STATE_DIM 4 // Kích thước vector trạng thái
#define CTRL_DIM 1 // Kích thước vector điều khiển
#define PRED_HORIZON 10 // Số bước dự báo
static void mdlInitializeSizes(SimStruct *S) {
ssSetNumInputPorts(S, 2);
ssSetInputPortWidth(S, 0, STATE_DIM); // [vx, vy, yaw_rate, y_pos]
ssSetInputPortWidth(S, 1, 2); // [y_ref, psi_ref]
ssSetNumOutputPorts(S, 1);
ssSetOutputPortWidth(S, 0, CTRL_DIM); // Góc đánh lái
ssSetNumSFcnParams(S, 0);
}
static void mdlInitializeSampleTimes(SimStruct *S) {
ssSetSampleTime(S, 0, 0.01); // Chu kỳ điều khiển 10ms
ssSetOffsetTime(S, 0, 0.0);
}
static void mdlOutputs(SimStruct *S, int_T tid) {
const real_T *state_vector = ssGetInputPortRealSignal(S, 0);
const real_T *reference_signal = ssGetInputPortRealSignal(S, 1);
// Giải nén trạng thái hiện tại
double current_vx = state_vector[0];
double current_vy = state_vector[1];
double current_yaw_rate = state_vector[2];
double current_lateral_pos = state_vector[3];
// Lấy giá trị tham chiếu
double target_lateral_pos = reference_signal[0];
double target_heading = reference_signal[1];
// Logic điều khiển đơn giản (PD controller)
double steering_gain = 0.15;
double damping_gain = 0.08;
double lateral_error = target_lateral_pos - current_lateral_pos;
double error_derivative = (lateral_error - previous_error) / 0.01;
double steering_command = steering_gain * lateral_error +
damping_gain * error_derivative;
// Lưu lại lỗi trước đó cho vòng lặp tiếp theo
previous_error = lateral_error;
// Giới hạn góc đánh lái trong phạm vi an toàn
if (steering_command > MAX_STEERING_ANGLE)
steering_command = MAX_STEERING_ANGLE;
else if (steering_command < -MAX_STEERING_ANGLE)
steering_command = -MAX_STEERING_ANGLE;
real_T *output = ssGetOutputPortRealSignal(S, 0);
output[0] = steering_command;
}
// Biến toàn cục lưu trữ trạng thái
static double previous_error = 0.0;
static const double MAX_STEERING_ANGLE = 0.5; // ±28.6 độ
5. Kỹ thuật gỡ lỗi mô phỏng liên kết
Một số vấn đề thường gặp và cách khắc phục:
Lỗi giao tiếp giữa Carsim và Simulink
- Kiểm tra tường lửa có chặn kết nối nội bộ không
- Xác nhận tiến trình
carsim_solver.exeđang chạy trong Task Manager - Tái tạo file giao diện S-Function trong Carsim
Kết quả mô phỏng không như mong đợi
- Chạy độc lập mô hình Carsim để kiểm tra động lực học cơ bản
- Thay MPC bằng bộ điều khiển PID đơn giản để kiểm tra giao diện
- Thêm Scope để theo dõi tín hiệu trung gian tại các điểm then chốt
Thời gian mô phỏng quá chậm
- Giảm số bước dự báo trong MPC
- Tối ưu hóa thuật toán giải QP
- Tắt các module không cần thiết trong mô hình xe
6. Phân tích và tối ưu kết quả
Các chỉ số đánh giá hiệu suất cho bài toán thay đổi làn:
| Tốc độ (km/h) | Sai số ngang lớn nhất (cm) | Sai số trung bình (cm) | Tốc độ thay đổi góc lái (deg/s) | Thời gian tính toán (ms) |
|---|---|---|---|---|
| 40 | 12.5 | 4.2 | 35.6 | 5.2 |
| 60 | 18.7 | 6.8 | 42.3 | 6.1 |
| 80 | 25.4 | 9.5 | 53.8 | 7.9 |
Hướng tối ưu khi kết quả chưa đạt yêu cầu:
- Điều chỉnh ma trận trọng số trong hàm chi phí MPC
- Tăng độ chính xác mô hình lốp (thông số Pacejka)
- Áp dụng kỹ thuật khởi tạo nóng (warm start) cho bộ giải QP