基于模糊控制的避障仿真实现MATLAB/Simulink方案

一、模糊控制避障核心原理

1.1 系统架构

传感器输入 → 模糊化 → 模糊推理 → 解模糊 → 控制输出 → 机器人运动
  (距离信息)   (隶属函数)  (规则库)   (清晰值)    (速度/转向)    (避障轨迹)

1.2 模糊控制器设计优势

特点 传统控制 模糊控制 避障优势
模型要求 精确数学模型 无需精确模型 适应环境不确定性
规则表达 数学方程 "如果-那么"语言规则 更符合人类驾驶经验
鲁棒性 对参数敏感 强鲁棒性 适应传感器噪声
实时性 计算复杂 推理速度快 满足实时避障需求

二、完整MATLAB仿真代码

%% 基于模糊控制的机器人避障仿真系统
clear; close all; clc;

%% 1. 参数初始化
% 仿真环境参数
map_size = [0, 100, 0, 100];  % 地图边界 [xmin, xmax, ymin, ymax]
obstacles = [30, 50, 8;       % 障碍物1 [x, y, radius]
             60, 30, 10;
             40, 70, 6;
             70, 60, 7;
             20, 20, 5];
goal = [90, 90];              % 目标点
start = [10, 10];             % 起始点

% 机器人参数
robot_pos = start;            % 初始位置
robot_radius = 3;             % 机器人半径
robot_theta = atan2(goal(2)-start(2), goal(1)-start(1)); % 初始朝向
max_speed = 2.0;              % 最大速度 (m/s)
max_steer = pi/4;             % 最大转向角 (rad)
safety_distance = 5;          % 安全距离

% 传感器参数
num_sensors = 8;              % 传感器数量
sensor_range = 20;            % 传感器探测范围 (m)
sensor_angles = linspace(-pi, pi, num_sensors+1); % 传感器角度
sensor_angles = sensor_angles(1:end-1);

% 仿真参数
dt = 0.1;                     % 时间步长 (s)
sim_time = 100;               % 总仿真时间 (s)
steps = ceil(sim_time/dt);

%% 2. 创建模糊逻辑控制器
fis = mamfis('Name', 'Obstacle_Avoidance');

% 2.1 输入变量定义
% 输入1: 前方障碍物距离 (0-20m)
fis = addInput(fis, [0, sensor_range], 'Name', 'front_distance');
fis = addMF(fis, 'front_distance', 'zmf', [3, 8], 'Name', 'Very_Near');
fis = addMF(fis, 'front_distance', 'trimf', [5, 10, 15], 'Name', 'Near');
fis = addMF(fis, 'front_distance', 'trimf', [12, 16, 20], 'Name', 'Far');
fis = addMF(fis, 'front_distance', 'smf', [18, 20], 'Name', 'Very_Far');

% 输入2: 左侧障碍物距离 (0-20m)
fis = addInput(fis, [0, sensor_range], 'Name', 'left_distance');
fis = addMF(fis, 'left_distance', 'zmf', [5, 10], 'Name', 'Near');
fis = addMF(fis, 'left_distance', 'trimf', [8, 12, 16], 'Name', 'Medium');
fis = addMF(fis, 'left_distance', 'smf', [14, 20], 'Name', 'Far');

% 输入3: 右侧障碍物距离 (0-20m)
fis = addInput(fis, [0, sensor_range], 'Name', 'right_distance');
fis = addMF(fis, 'right_distance', 'zmf', [5, 10], 'Name', 'Near');
fis = addMF(fis, 'right_distance', 'trimf', [8, 12, 16], 'Name', 'Medium');
fis = addMF(fis, 'right_distance', 'smf', [14, 20], 'Name', 'Far');

% 输入4: 目标方向偏差 (-pi到pi rad)
fis = addInput(fis, [-pi, pi], 'Name', 'goal_error');
fis = addMF(fis, 'goal_error', 'trapmf', [-pi, -pi, -pi/2, -pi/6], 'Name', 'Left_High');
fis = addMF(fis, 'goal_error', 'trimf', [-pi/3, -pi/12, 0], 'Name', 'Left_Low');
fis = addMF(fis, 'goal_error', 'trimf', [-pi/12, 0, pi/12], 'Name', 'Straight');
fis = addMF(fis, 'goal_error', 'trimf', [0, pi/12, pi/3], 'Name', 'Right_Low');
fis = addMF(fis, 'goal_error', 'trapmf', [pi/6, pi/2, pi, pi], 'Name', 'Right_High');

% 2.2 输出变量定义
% 输出1: 转向角 (-pi/4到pi/4 rad)
fis = addOutput(fis, [-max_steer, max_steer], 'Name', 'steering_angle');
fis = addMF(fis, 'steering_angle', 'trimf', [-max_steer, -max_steer/2, 0], 'Name', 'Turn_Left_High');
fis = addMF(fis, 'steering_angle', 'trimf', [-max_steer/2, -max_steer/4, 0], 'Name', 'Turn_Left_Low');
fis = addMF(fis, 'steering_angle', 'trimf', [-max_steer/8, 0, max_steer/8], 'Name', 'Go_Straight');
fis = addMF(fis, 'steering_angle', 'trimf', [0, max_steer/4, max_steer/2], 'Name', 'Turn_Right_Low');
fis = addMF(fis, 'steering_angle', 'trimf', [0, max_steer/2, max_steer], 'Name', 'Turn_Right_High');

% 输出2: 速度 (0到最大速度 m/s)
fis = addOutput(fis, [0, max_speed], 'Name', 'speed');
fis = addMF(fis, 'speed', 'zmf', [0.2, 0.5], 'Name', 'Very_Slow');
fis = addMF(fis, 'speed', 'trimf', [0.3, 0.6, 0.9], 'Name', 'Slow');
fis = addMF(fis, 'speed', 'trimf', [0.6, 0.9, 1.2], 'Name', 'Medium');
fis = addMF(fis, 'speed', 'smf', [1.0, max_speed], 'Name', 'Fast');

% 2.3 模糊规则库(基于经验的避障规则)
rules = [
    "如果 front_distance 是 Very_Near 那么 steering_angle 是 Turn_Left_High 且 speed 是 Very_Slow", 1;
    "如果 front_distance 是 Near 且 left_distance 是 Near 那么 steering_angle 是 Turn_Right_High 且 speed 是 Slow", 1;
    "如果 front_distance 是 Near 且 right_distance 是 Near 那么 steering_angle 是 Turn_Left_High 且 speed 是 Slow", 1;
    "如果 front_distance 是 Far 且 goal_error 是 Left_High 那么 steering_angle 是 Turn_Left_Low 且 speed 是 Medium", 1;
    "如果 front_distance 是 Far 且 goal_error 是 Right_High 那么 steering_angle 是 Turn_Right_Low 且 speed 是 Medium", 1;
    "如果 front_distance 是 Very_Far 且 goal_error 是 Straight 那么 steering_angle 是 Go_Straight 且 speed 是 Fast", 1;
    "如果 left_distance 是 Near 且 right_distance 是 Far 那么 steering_angle 是 Turn_Right_Low 且 speed 是 Medium", 0.8;
    "如果 right_distance 是 Near 且 left_distance 是 Far 那么 steering_angle 是 Turn_Left_Low 且 speed 是 Medium", 0.8;
    "如果 front_distance 是 Near 且 left_distance 是 Far 且 right_distance 是 Far 那么 steering_angle 是 Go_Straight 且 speed 是 Slow", 0.9;
    "如果 front_distance 是 Very_Far 且 goal_error 是 Left_Low 那么 steering_angle 是 Turn_Left_Low 且 speed 是 Fast", 0.7;
    "如果 front_distance 是 Very_Far 且 goal_error 是 Right_Low 那么 steering_angle 是 Turn_Right_Low 且 speed 是 Fast", 0.7;
];

fis = addRule(fis, rules);

% 2.4 可视化模糊系统
figure('Position', [100, 100, 1200, 800]);
subplot(2,3,1); plotmf(fis, 'input', 1); title('前方距离隶属函数');
subplot(2,3,2); plotmf(fis, 'input', 2); title('左侧距离隶属函数');
subplot(2,3,3); plotmf(fis, 'input', 3); title('右侧距离隶属函数');
subplot(2,3,4); plotmf(fis, 'input', 4); title('目标偏差隶属函数');
subplot(2,3,5); plotmf(fis, 'output', 1); title('转向角隶属函数');
subplot(2,3,6); plotmf(fis, 'output', 2); title('速度隶属函数');

%% 3. 仿真主循环
% 初始化记录变量
trajectory = zeros(steps, 2);
trajectory(1,:) = robot_pos;
sensor_readings = zeros(steps, num_sensors);
controls = zeros(steps, 2);  % [转向角, 速度]
dist_to_goal = zeros(steps, 1);
dist_to_goal(1) = norm(robot_pos - goal);
collision_flag = false;

fprintf('开始模糊控制避障仿真...\n');
fprintf('目标点: (%.1f, %.1f)\n', goal(1), goal(2));

% 创建实时可视化
figure('Position', [100, 100, 1000, 800]);
h_ax = axes;
hold on;

% 绘制静态元素
rectangle('Position', [map_size(1), map_size(3), ...
          map_size(2)-map_size(1), map_size(4)-map_size(3)], ...
          'EdgeColor', 'k', 'LineWidth', 2);

% 绘制障碍物
for i = 1:size(obstacles, 1)
    viscircles(obstacles(i,1:2), obstacles(i,3), ...
               'Color', [0.7, 0.2, 0.2], 'LineWidth', 1.5);
    % 添加安全边界
    viscircles(obstacles(i,1:2), obstacles(i,3) + safety_distance, ...
               'Color', [1, 0.8, 0.8], 'LineWidth', 0.5, 'LineStyle', '--');
end

% 绘制起始点和目标点
plot(start(1), start(2), 'go', 'MarkerSize', 10, 'MarkerFaceColor', 'g');
text(start(1)+2, start(2), '起点', 'FontSize', 10, 'FontWeight', 'bold');
plot(goal(1), goal(2), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
text(goal(1)+2, goal(2), '目标', 'FontSize', 10, 'FontWeight', 'bold');

% 初始化动态元素
h_robot = rectangle('Position', [robot_pos(1)-robot_radius, robot_pos(2)-robot_radius, ...
                     2*robot_radius, 2*robot_radius], ...
                    'Curvature', [1,1], 'FaceColor', [0.2, 0.5, 0.8], ...
                    'EdgeColor', 'b', 'LineWidth', 2);
                
h_direction = quiver(robot_pos(1), robot_pos(2), ...
                     cos(robot_theta), sin(robot_theta), ...
                     robot_radius*2, 'Color', 'k', 'LineWidth', 2, ...
                     'MaxHeadSize', 2);
                 
h_trajectory = plot(robot_pos(1), robot_pos(2), 'b-', 'LineWidth', 1.5);
h_sensors = gobjects(num_sensors, 1);
for i = 1:num_sensors
    h_sensors(i) = plot([robot_pos(1), robot_pos(1)], ...
                        [robot_pos(2), robot_pos(2)], ...
                        'c-', 'LineWidth', 0.5);
end

axis equal; grid on; box on;
xlim([map_size(1)-5, map_size(2)+5]);
ylim([map_size(3)-5, map_size(4)+5]);
title('模糊控制避障仿真');
xlabel('X坐标 (m)'); ylabel('Y坐标 (m)');

%% 主仿真循环
for step = 2:steps
    % 3.1 传感器模拟(计算到最近障碍物的距离)
    sensor_dist = sensor_range * ones(1, num_sensors);
    
    for sensor_idx = 1:num_sensors
        sensor_angle = robot_theta + sensor_angles(sensor_idx);
        sensor_end = robot_pos + sensor_range * [cos(sensor_angle), sin(sensor_angle)];
        
        % 检查与每个障碍物的交点
        for obs_idx = 1:size(obstacles, 1)
            obs_pos = obstacles(obs_idx, 1:2);
            obs_radius = obstacles(obs_idx, 3);
            
            % 计算线段与圆的交点
            [intersect, points] = line_circle_intersection(robot_pos, sensor_end, obs_pos, obs_radius);
            
            if intersect
                dist = norm(points(1,:) - robot_pos);
                if dist < sensor_dist(sensor_idx)
                    sensor_dist(sensor_idx) = dist;
                end
            end
        end
    end
    
    sensor_readings(step,:) = sensor_dist;
    
    % 3.2 提取关键距离信息(用于模糊控制器输入)
    front_idx = find(abs(sensor_angles) == min(abs(sensor_angles)));
    left_idx = find(sensor_angles < 0);
    right_idx = find(sensor_angles > 0);
    
    front_dist = min(sensor_dist(front_idx));
    left_dist = min(sensor_dist(left_idx));
    right_dist = min(sensor_dist(right_idx));
    
    % 3.3 计算目标方向偏差
    goal_vector = goal - robot_pos;
    goal_angle = atan2(goal_vector(2), goal_vector(1));
    angle_error = wrapToPi(goal_angle - robot_theta); % 归一化到[-pi, pi]
    
    % 3.4 模糊推理
    fis_input = [front_dist, left_dist, right_dist, angle_error];
    fis_output = evalfis(fis, fis_input);
    
    steering_angle = fis_output(1);
    speed = fis_output(2);
    
    % 限制输出范围
    steering_angle = max(min(steering_angle, max_steer), -max_steer);
    speed = max(min(speed, max_speed), 0);
    
    controls(step,:) = [steering_angle, speed];
    
    % 3.5 更新机器人状态(简单运动学模型)
    robot_theta = robot_theta + steering_angle * dt;
    robot_theta = wrapToPi(robot_theta); % 保持角度在[-pi, pi]
    
    robot_pos = robot_pos + speed * dt * [cos(robot_theta), sin(robot_theta)];
    
    % 检查边界
    robot_pos(1) = max(min(robot_pos(1), map_size(2)-1), map_size(1)+1);
    robot_pos(2) = max(min(robot_pos(2), map_size(4)-1), map_size(3)+1);
    
    trajectory(step,:) = robot_pos;
    dist_to_goal(step) = norm(robot_pos - goal);
    
    % 3.6 碰撞检测
    collision = false;
    for obs_idx = 1:size(obstacles, 1)
        if norm(robot_pos - obstacles(obs_idx,1:2)) < (obstacles(obs_idx,3) + robot_radius)
            collision = true;
            collision_flag = true;
            fprintf('步骤 %d: 发生碰撞!\n', step);
            break;
        end
    end
    
    if collision
        speed = 0; % 停止
    end
    
    % 3.7 更新可视化
    set(h_robot, 'Position', [robot_pos(1)-robot_radius, robot_pos(2)-robot_radius, ...
                              2*robot_radius, 2*robot_radius]);
    
    set(h_direction, 'XData', robot_pos(1), 'YData', robot_pos(2), ...
                     'UData', cos(robot_theta)*robot_radius*2, ...
                     'VData', sin(robot_theta)*robot_radius*2);
    
    set(h_trajectory, 'XData', trajectory(1:step,1), ...
                      'YData', trajectory(1:step,2));
    
    % 更新传感器线
    for sensor_idx = 1:num_sensors
        sensor_angle = robot_theta + sensor_angles(sensor_idx);
        sensor_end = robot_pos + sensor_dist(sensor_idx) * [cos(sensor_angle), sin(sensor_angle)];
        
        if sensor_dist(sensor_idx) < sensor_range
            line_color = [1, 0, 0]; % 红色表示检测到障碍物
        else
            line_color = [0, 1, 1]; % 青色表示无障碍物
        end
        
        set(h_sensors(sensor_idx), ...
            'XData', [robot_pos(1), sensor_end(1)], ...
            'YData', [robot_pos(2), sensor_end(2)], ...
            'Color', line_color);
    end
    
    % 3.8 检查是否到达目标
    if dist_to_goal(step) < 3
        fprintf('步骤 %d: 成功到达目标!\n', step);
        break;
    end
    
    % 3.9 检查超时
    if step > steps-10
        fprintf('仿真超时,未到达目标\n');
        break;
    end
    
    % 暂停以便观察
    pause(0.01);
    
    % 刷新图形
    drawnow;
end

%% 4. 性能分析与可视化
fprintf('\n仿真完成!\n');
fprintf('最终位置: (%.2f, %.2f)\n', robot_pos(1), robot_pos(2));
fprintf('距离目标: %.2f m\n', dist_to_goal(step));
fprintf('是否碰撞: %s\n', string(collision_flag));

% 4.1 创建性能分析图
figure('Position', [100, 100, 1400, 600]);

% 轨迹分析
subplot(2,3,1);
plot(trajectory(1:step,1), trajectory(1:step,2), 'b-', 'LineWidth', 2);
hold on;
for i = 1:size(obstacles, 1)
    rectangle('Position', [obstacles(i,1)-obstacles(i,3), obstacles(i,2)-obstacles(i,3), ...
              2*obstacles(i,3), 2*obstacles(i,3)], 'Curvature', [1,1], ...
              'EdgeColor', 'r', 'FaceColor', [1,0.8,0.8]);
end
plot(start(1), start(2), 'go', 'MarkerSize', 10, 'MarkerFaceColor', 'g');
plot(goal(1), goal(2), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
plot(robot_pos(1), robot_pos(2), 'bo', 'MarkerSize', 8, 'MarkerFaceColor', 'b');
title('机器人运动轨迹');
xlabel('X (m)'); ylabel('Y (m)');
axis equal; grid on; legend('轨迹', '障碍物', '起点', '目标', '终点');

% 传感器读数
subplot(2,3,2);
sensor_time = (1:step) * dt;
for i = 1:min(4, num_sensors)
    plot(sensor_time, sensor_readings(1:step,i), 'LineWidth', 1.5);
    hold on;
end
title('传感器距离读数');
xlabel('时间 (s)'); ylabel('距离 (m)');
grid on; legend('传感器1', '传感器2', '传感器3', '传感器4');
ylim([0, sensor_range]);

% 控制输出
subplot(2,3,3);
yyaxis left;
plot(sensor_time, controls(1:step,1)*180/pi, 'b-', 'LineWidth', 2);
ylabel('转向角 (°)');
ylim([-max_steer*180/pi, max_steer*180/pi]);

yyaxis right;
plot(sensor_time, controls(1:step,2), 'r-', 'LineWidth', 2);
ylabel('速度 (m/s)');
ylim([0, max_speed]);
title('控制输出');
xlabel('时间 (s)'); grid on;
legend('转向角', '速度');

% 距离目标变化
subplot(2,3,4);
plot(sensor_time, dist_to_goal(1:step), 'm-', 'LineWidth', 2);
title('到目标的距离');
xlabel('时间 (s)'); ylabel('距离 (m)');
grid on;

% 模糊规则激活度
subplot(2,3,5);
rule_firing = zeros(step, size(rules,1));
for t = 1:step
    fis_input = [sensor_readings(t,front_idx(1)), ...
                 min(sensor_readings(t,left_idx)), ...
                 min(sensor_readings(t,right_idx)), ...
                 angle_error];
    [~, ~, rule_output] = evalfis(fis, fis_input);
    rule_firing(t,:) = rule_output;
end
imagesc(sensor_time, 1:size(rules,1), rule_firing');
colorbar; colormap(jet);
title('模糊规则激活强度');
xlabel('时间 (s)'); ylabel('规则编号');
set(gca, 'YDir', 'normal');

% 3D控制曲面
subplot(2,3,6);
[x_grid, y_grid] = meshgrid(linspace(0, sensor_range, 20), ...
                             linspace(-max_steer, max_steer, 20));
z_grid = zeros(size(x_grid));

for i = 1:numel(x_grid)
    % 固定其他输入,查看front_distance和goal_error对steering的影响
    test_input = [x_grid(i), sensor_range/2, sensor_range/2, y_grid(i)];
    output = evalfis(fis, test_input);
    z_grid(i) = output(1); % steering_angle
end

surf(x_grid, y_grid, z_grid);
title('控制规则曲面 (转向角)');
xlabel('前方距离 (m)'); ylabel('目标偏差 (rad)'); zlabel('转向角 (rad)');
grid on; view(45, 30);

%% 5. 对比实验:模糊控制 vs PID控制
fprintf('\n\n对比实验:模糊控制 vs PID控制\n');

% PID控制器参数
Kp = 0.5; Ki = 0.01; Kd = 0.1;
pid_integral = 0;
pid_last_error = 0;

% 重新初始化进行对比
robot_pos_pid = start;
robot_theta_pid = atan2(goal(2)-start(2), goal(1)-start(1));
trajectory_pid = zeros(steps, 2);
trajectory_pid(1,:) = robot_pos_pid;

for step_pid = 2:steps
    % 传感器测量(使用相同的传感器模型)
    sensor_dist_pid = sensor_range * ones(1, num_sensors);
    
    for sensor_idx = 1:num_sensors
        sensor_angle = robot_theta_pid + sensor_angles(sensor_idx);
        sensor_end = robot_pos_pid + sensor_range * [cos(sensor_angle), sin(sensor_angle)];
        
        for obs_idx = 1:size(obstacles, 1)
            [intersect, points] = line_circle_intersection(robot_pos_pid, sensor_end, ...
                                                          obstacles(obs_idx,1:2), obstacles(obs_idx,3));
            if intersect
                dist = norm(points(1,:) - robot_pos_pid);
                if dist < sensor_dist_pid(sensor_idx)
                    sensor_dist_pid(sensor_idx) = dist;
                end
            end
        end
    end
    
    % PID避障:简单启发式规则
    front_dist_pid = min(sensor_dist_pid(front_idx));
    
    % 如果前方有障碍物,转向
    if front_dist_pid < safety_distance
        % 检查左右哪边更安全
        left_dist_pid = min(sensor_dist_pid(left_idx));
        right_dist_pid = min(sensor_dist_pid(right_idx));
        
        if left_dist_pid > right_dist_pid
            steering_pid = max_steer/2; % 向左转
        else
            steering_pid = -max_steer/2; % 向右转
        end
        
        speed_pid = max_speed * 0.3; % 减速
    else
        % 朝向目标
        goal_vector = goal - robot_pos_pid;
        goal_angle = atan2(goal_vector(2), goal_vector(1));
        angle_error = wrapToPi(goal_angle - robot_theta_pid);
        
        % PID控制
        pid_integral = pid_integral + angle_error * dt;
        pid_derivative = (angle_error - pid_last_error) / dt;
        steering_pid = Kp * angle_error + Ki * pid_integral + Kd * pid_derivative;
        pid_last_error = angle_error;
        
        steering_pid = max(min(steering_pid, max_steer), -max_steer);
        speed_pid = max_speed * 0.8;
    end
    
    % 更新状态
    robot_theta_pid = robot_theta_pid + steering_pid * dt;
    robot_theta_pid = wrapToPi(robot_theta_pid);
    
    robot_pos_pid = robot_pos_pid + speed_pid * dt * [cos(robot_theta_pid), sin(robot_theta_pid)];
    
    % 边界检查
    robot_pos_pid(1) = max(min(robot_pos_pid(1), map_size(2)-1), map_size(1)+1);
    robot_pos_pid(2) = max(min(robot_pos_pid(2), map_size(4)-1), map_size(3)+1);
    
    trajectory_pid(step_pid,:) = robot_pos_pid;
    
    if norm(robot_pos_pid - goal) < 3
        break;
    end
end

% 对比可视化
figure('Position', [100, 100, 1200, 500]);

subplot(1,2,1);
plot(trajectory(1:step,1), trajectory(1:step,2), 'b-', 'LineWidth', 2);
hold on;
plot(trajectory_pid(1:step_pid,1), trajectory_pid(1:step_pid,2), 'r--', 'LineWidth', 2);
for i = 1:size(obstacles, 1)
    rectangle('Position', [obstacles(i,1)-obstacles(i,3), obstacles(i,2)-obstacles(i,3), ...
              2*obstacles(i,3), 2*obstacles(i,3)], 'Curvature', [1,1], ...
              'EdgeColor', 'k', 'FaceColor', [0.9,0.9,0.9]);
end
plot(start(1), start(2), 'go', 'MarkerSize', 10, 'MarkerFaceColor', 'g');
plot(goal(1), goal(2), 'mo', 'MarkerSize', 10, 'MarkerFaceColor', 'm');
legend('模糊控制', 'PID控制', '障碍物', '起点', '目标');
title('控制方法对比');
xlabel('X (m)'); ylabel('Y (m)'); axis equal; grid on;

subplot(1,2,2);
performance_metrics = {
    '路径长度', norm(diff(trajectory(1:step,:)), 'fro'), norm(diff(trajectory_pid(1:step_pid,:)), 'fro');
    '平均速度', mean(controls(1:step,2)), mean(speed_pid);
    '转向波动', std(controls(1:step,1)), std(steering_pid);
    '到达时间', step*dt, step_pid*dt;
    '最小障碍距离', min(min(sensor_readings(1:step,:))), min(min(sensor_dist_pid));
};

bar_data = [cell2mat(performance_metrics(:,2)), cell2mat(performance_metrics(:,3))];
h_bar = bar(bar_data);
set(gca, 'XTickLabel', performance_metrics(:,1), 'XTickLabelRotation', 45);
ylabel('数值');
title('性能指标对比');
legend('模糊控制', 'PID控制');
grid on;

%% 辅助函数定义
function [intersect, points] = line_circle_intersection(p1, p2, center, radius)
    % 计算线段与圆的交点
    intersect = false;
    points = [];
    
    % 线段向量
    d = p2 - p1;
    f = p1 - center;
    
    % 二次方程系数
    a = dot(d, d);
    b = 2 * dot(f, d);
    c = dot(f, f) - radius^2;
    
    discriminant = b^2 - 4*a*c;
    
    if discriminant >= 0
        discriminant = sqrt(discriminant);
        t1 = (-b - discriminant) / (2*a);
        t2 = (-b + discriminant) / (2*a);
        
        % 检查交点是否在线段上
        if t1 >= 0 && t1 <= 1
            intersect = true;
            points = [points; p1 + t1*d];
        end
        
        if t2 >= 0 && t2 <= 1 && abs(t1-t2) > 1e-6
            intersect = true;
            points = [points; p1 + t2*d];
        end
    end
end

function angle = wrapToPi(angle)
    % 将角度包装到[-pi, pi]范围
    angle = mod(angle + pi, 2*pi) - pi;
end

三、Simulink模糊控制避障系统

对于更复杂的系统,可以使用Simulink实现:

%% Simulink模糊避障系统构建指南

% 1. 创建Simulink模型组件
% - 机器人动力学模型子系统
% - 传感器模拟子系统
% - 模糊逻辑控制器(FLC)模块
% - 环境与障碍物模块
% - 可视化显示模块

% 2. 关键Simulink模块配置
% a) 模糊逻辑控制器模块:
%    - 使用Fuzzy Logic Controller模块
%    - 载入上面创建的fis对象
%    - 采样时间设置为dt

% b) 传感器子系统:
%    - 使用MATLAB Function模块实现距离计算
%    - 输出多个距离信号到模糊控制器

% c) 机器人动力学:
%    - 使用积分器模块实现位置更新
%    - 考虑非完整约束(如差速驱动模型)

% 3. 仿真配置
%    - 使用可变步长求解器ode45
%    - 最大步长设置为0.1
%    - 启用数据记录用于分析

%% 差速驱动机器人模型示例代码
function [v_left, v_right] = differential_drive_controller(steering, speed, robot_params)
    % 差速驱动控制
    % 输入: steering - 期望转向角
    %       speed - 期望速度
    %       robot_params - 机器人参数(轮距等)
    
    wheel_base = robot_params.wheel_base;
    max_wheel_speed = robot_params.max_wheel_speed;
    
    % 差速驱动运动学
    linear_vel = speed;
    angular_vel = (2 * linear_vel * tan(steering)) / wheel_base;
    
    % 计算左右轮速度
    v_left = linear_vel - (angular_vel * wheel_base / 2);
    v_right = linear_vel + (angular_vel * wheel_base / 2);
    
    % 限制轮速
    v_left = max(min(v_left, max_wheel_speed), -max_wheel_speed);
    v_right = max(min(v_right, max_wheel_speed), -max_wheel_speed);
end

四、算法优化与进阶

4.1 自适应模糊控制

% 自适应调整模糊规则权重
function updated_fis = adapt_fuzzy_rules(fis, performance_error, learning_rate)
    % 根据性能误差调整规则权重
    rules = fis.Rules;
    
    for i = 1:length(rules)
        % 如果这条规则在上次决策中激活度高但效果差,降低权重
        if rules(i).FiringStrength > 0.5 && performance_error > 0.1
            rules(i).Weight = max(0.1, rules(i).Weight - learning_rate * performance_error);
        elseif rules(i).FiringStrength > 0.5 && performance_error < -0.05
            rules(i).Weight = min(1.0, rules(i).Weight - learning_rate * performance_error);
        end
    end
    
    fis.Rules = rules;
    updated_fis = fis;
end

4.2 与UKF融合

% UKF状态估计 + 模糊控制决策
function [control_output, estimated_state] = ukf_fuzzy_fusion(sensor_data, fis, prev_state)
    % UKF用于状态估计
    [estimated_state, state_covariance] = ukf_state_estimation(prev_state, sensor_data);
    
    % 从估计状态提取模糊控制器输入
    front_dist_est = estimated_state(1);
    left_dist_est = estimated_state(2);
    right_dist_est = estimated_state(3);
    goal_error_est = estimated_state(4);
    
    % 考虑估计不确定性调整模糊输入
    uncertainty_factor = diag(state_covariance);
    adjusted_inputs = [
        front_dist_est * (1 + 0.1*uncertainty_factor(1)),
        left_dist_est * (1 + 0.1*uncertainty_factor(2)),
        right_dist_est * (1 + 0.1*uncertainty_factor(3)),
        goal_error_est
    ];
    
    % 模糊推理
    control_output = evalfis(fis, adjusted_inputs);
end

参考代码 基于模糊控制的避障仿真 www.youwenfan.com/contentcno/96418.html

五、部署建议

  1. 计算优化

    • 使用查表法替代实时模糊推理
    • 简化隶属函数数量(5-7个为宜)
    • 考虑使用ANFIS(自适应神经模糊系统)自动优化规则
  2. 传感器融合

    • 结合激光雷达、摄像头、超声波等多传感器
    • 使用卡尔曼滤波融合传感器数据
    • 考虑传感器故障容错机制
  3. 实时性保证

    • 在嵌入式平台(如ROS+STM32)上部署
    • 使用固定点运算替代浮点
    • 设定最大推理时间限制
posted @ 2025-12-23 09:58  令小飞  阅读(28)  评论(0)    收藏  举报